<!DOCTYPE html>
<html lang="zh-Hans">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 3.8.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="/lib/font-awesome/css/all.min.css">

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"yoursite.com","root":"/","scheme":"Gemini","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":false,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},"path":"search.xml"};
  </script>

  <meta name="description" content="A Quiet Departure.">
<meta property="og:type" content="website">
<meta property="og:title" content="Feng&#39;s Blog">
<meta property="og:url" content="http://yoursite.com/page/9/index.html">
<meta property="og:site_name" content="Feng&#39;s Blog">
<meta property="og:description" content="A Quiet Departure.">
<meta property="og:locale" content="zh-Hans">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Feng&#39;s Blog">
<meta name="twitter:description" content="A Quiet Departure.">

<link rel="canonical" href="http://yoursite.com/page/9/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : true,
    isPost : false,
    lang   : 'zh-Hans'
  };
</script>

  <title>Feng's Blog</title>
  






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="Toggle navigation bar">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <h1 class="site-title">Feng's Blog</h1>
      <span class="logo-line-after"><i></i></span>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
    </div>
  </div>
</div>




<nav class="site-nav">
  <ul id="menu" class="main-menu menu">
        <li class="menu-item menu-item-home">

    <a href="/" rel="section"><i class="fa fa-home fa-fw"></i>Home</a>

  </li>
        <li class="menu-item menu-item-about">

    <a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>About</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>Tags</a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>Categories</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>Archives</a>

  </li>
  </ul>
</nav>




</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content index posts-expand">
            
      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-Hans">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2019/10/15/Mysql系列之备忘录/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="Fengorz">
      <meta itemprop="description" content="A Quiet Departure.">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Feng's Blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/2019/10/15/Mysql系列之备忘录/" class="post-title-link" itemprop="url">Mysql系列之备忘录</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2019-10-15 21:36:49" itemprop="dateCreated datePublished" datetime="2019-10-15T21:36:49+08:00">2019-10-15</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2020-07-30 23:42:46" itemprop="dateModified" datetime="2020-07-30T23:42:46+08:00">2020-07-30</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">In</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Mysql/" itemprop="url" rel="index"><span itemprop="name">Mysql</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <h1 id="规范"><a href="#规范" class="headerlink" title="规范"></a>规范</h1><p><a href="https://help.aliyun.com/wordpower/2596091-1.html" target="_blank" rel="noopener">alibabaMysql开发规范和常见问题处理</a><br><a href="https://learnku.com/articles/25116" target="_blank" rel="noopener">参考1</a></p>
<h1 id="TodoItem"><a href="#TodoItem" class="headerlink" title="TodoItem"></a>TodoItem</h1><h2 id="SHOW-ENGINE-INNODB-STATUS-todo"><a href="#SHOW-ENGINE-INNODB-STATUS-todo" class="headerlink" title="SHOW ENGINE INNODB STATUS; todo"></a>SHOW ENGINE INNODB STATUS; todo</h2><h2 id="建模工具PDMan-todo"><a href="#建模工具PDMan-todo" class="headerlink" title="建模工具PDMan todo"></a>建模工具PDMan todo</h2><p>还是可视化视图清晰点，还可以导出自动生成sql。</p>
<h1 id="Basic-Knowledge"><a href="#Basic-Knowledge" class="headerlink" title="Basic Knowledge"></a>Basic Knowledge</h1><h2 id="常用命令"><a href="#常用命令" class="headerlink" title="常用命令"></a>常用命令</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"># 设置主键自增初始值</span><br><span class="line">alter table t_ins_sequence AUTO_INCREMENT = 100000;</span><br><span class="line"># 修改表名</span><br><span class="line">alter table sys_user_role rename to sys_user_role_rel;</span><br><span class="line"># 查询数据库里面各个表的大小</span><br><span class="line">SELECT CONCAT(table_schema,&apos;.&apos;,table_name) AS &apos;Table Name&apos;,</span><br><span class="line">    table_rows AS &apos;Number of Rows&apos;,</span><br><span class="line">    CONCAT(ROUND(data_length/(1024*1024*1024),6),&apos; G&apos;) AS &apos;Data Size&apos;,</span><br><span class="line">    CONCAT(ROUND(index_length/(1024*1024*1024),6),&apos; G&apos;) AS &apos;Index Size&apos; ,</span><br><span class="line">    CONCAT(ROUND((data_length+index_length)/(1024*1024*1024),6),&apos; G&apos;) AS&apos;Total&apos;</span><br><span class="line">FROM information_schema.TABLES</span><br><span class="line">WHERE table_schema LIKE &apos;inspect_db&apos;;</span><br><span class="line"># 修改主键自增</span><br><span class="line">alter table word_fetch_queue modify queue_id int auto_increment;</span><br><span class="line"># 修改主键被外键约束show create table table_name;</span><br><span class="line"></span><br><span class="line">SET FOREIGN_KEY_CHECKS = 0;</span><br><span class="line"># 约束解除，进行修改，完了还原</span><br><span class="line">SET FOREIGN_KEY_CHECKS = 1;</span><br><span class="line"># 查询表的建表DDL</span><br><span class="line">show create table table_name;</span><br><span class="line"># 查看表空间模式</span><br><span class="line">show variables like &apos;%innodb_file_per_table%&apos; ;</span><br><span class="line"># Mysql基本可以将schema当成database；下面二个命令都会创建对应数据库</span><br><span class="line">create schema xxxName;</span><br><span class="line">create databse xxxName;</span><br><span class="line"># 查询某个字符开头的所有表</span><br><span class="line">show tables like &apos;ACT_%&apos;;</span><br></pre></td></tr></table></figure>
<h2 id="执行计划EXPLAIN"><a href="#执行计划EXPLAIN" class="headerlink" title="执行计划EXPLAIN"></a>执行计划EXPLAIN</h2><p><a href="https://www.cnblogs.com/tufujie/p/9413852.html" target="_blank" rel="noopener">Mysql执行计划教程</a></p>
<h2 id="Mysql的级联更新"><a href="#Mysql的级联更新" class="headerlink" title="Mysql的级联更新"></a>Mysql的级联更新</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">update tb1,</span><br><span class="line">tb2</span><br><span class="line">set tb1.a=tb2.a,tb1.b=tb2.b</span><br><span class="line">where tb1.id=tb2.id;</span><br><span class="line"></span><br><span class="line">update tb1,</span><br><span class="line">(select * from tb2 where xxx) as tb2</span><br><span class="line">set tb1.a=tb2.a,tb1.b=tb2.b</span><br><span class="line">where tb1.id=tb2.id;</span><br><span class="line"></span><br><span class="line">update (select * from tb1 group by C) as temp,</span><br><span class="line">       tb2,</span><br><span class="line">       tb1</span><br><span class="line">set tb1.a = tb2.a,</span><br><span class="line">    tb1.b = tb2.b</span><br><span class="line">where tb1.id = tb2.id and</span><br><span class="line">      temp.id = tb2.id;</span><br><span class="line"></span><br><span class="line">update tb1 left join tb2 on tb1.id = tb2.id</span><br><span class="line">set tb1.a = tb2.a,</span><br><span class="line">    tb1.b = tb2.b</span><br><span class="line">where xxx;</span><br></pre></td></tr></table></figure>
<h2 id="Mysql和Oracle的Sql的不同之处"><a href="#Mysql和Oracle的Sql的不同之处" class="headerlink" title="Mysql和Oracle的Sql的不同之处"></a>Mysql和Oracle的Sql的不同之处</h2><p>delete在oracle中是支持别名的，mysql不支持<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">delete from table_name tn;// mysql error</span><br></pre></td></tr></table></figure></p>
<p>Oracle可以直接sequence，Mysql不能，如果非要在Mysql使用类似Oracle的sequence功能，可以通过一张表来模拟，参考：<br><a href="https://blog.csdn.net/u012373815/article/details/78179411" title="标题" target="_blank" rel="noopener">https://blog.csdn.net/u012373815/article/details/78179411</a></p>
<p>Mysql没有类似Oracle一样的表空间概念，mysql的表空间分为两个文件一个是<em>.ibd文件存储数据索引…等数据信息，且只针对一张表，还有一个文件是</em>.frm这个文件是存储表的元数据。</p>
<h2 id="time、timestamp、date、datetime"><a href="#time、timestamp、date、datetime" class="headerlink" title="time、timestamp、date、datetime"></a>time、timestamp、date、datetime</h2><p>DATE: It is used for values with a date part but no time part. MySQL retrieves and displays DATE values in YYYY-MM-DD format. The supported range is 1000-01-01 to 9999-12-31.</p>
<p>DATETIME: It is used for values that contain both date and time parts. MySQL retrieves and displays DATETIME values in YYYY-MM-DD HH:MM:SS format. The supported range is 1000-01-01 00:00:00 to 9999-12-31 23:59:59.</p>
<p>TIMESTAMP: It is used for values that contain both date and time parts. TIMESTAMP has a range of 1970-01-01 00:00:01 UTC to 2038-01-19 03:14:07 UTC.</p>
<p>TIME: Its values are in HH:MM:SS format (or HHH:MM:SS format for large hours values). TIME values may range from -838:59:59 to 838:59:59. The hours part may be so large because the TIME type can be used not only to represent a time of day (which must be less than 24 hours), but also elapsed time or a time interval between two events (which may be much greater than 24 hours, or even negative).</p>
<h2 id="char-vs-varchar"><a href="#char-vs-varchar" class="headerlink" title="char vs varchar"></a>char vs varchar</h2><p>MySQL - CHAR vs VARCHAR - What is the difference? CHAR is fixed length while VARCHAR is variable length. That means, a CHAR(x) string has exactly x characters in length, including spaces. A VARCHAR(x) string can have up to x characters and it cuts off trailing spaces, thus might be shorter than the declared length.</p>
<h2 id="Mysql一对多数据显示成一行"><a href="#Mysql一对多数据显示成一行" class="headerlink" title="Mysql一对多数据显示成一行"></a>Mysql一对多数据显示成一行</h2><p><a href="https://www.cnblogs.com/lucky-girl/p/9482169.html" target="_blank" rel="noopener">使用GROUP_CONCAT</a></p>
<h2 id="Mysql常用函数大全"><a href="#Mysql常用函数大全" class="headerlink" title="Mysql常用函数大全"></a>Mysql常用函数大全</h2><p><a href="https://www.cnblogs.com/panchanggui/p/10652322.html" target="_blank" rel="noopener">常用函数</a></p>
<h2 id="数据库的导入导出（数据迁移、数据备份恢复）"><a href="#数据库的导入导出（数据迁移、数据备份恢复）" class="headerlink" title="数据库的导入导出（数据迁移、数据备份恢复）"></a>数据库的导入导出（数据迁移、数据备份恢复）</h2><h3 id="快速备份某个表"><a href="#快速备份某个表" class="headerlink" title="快速备份某个表"></a>快速备份某个表</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">DROP TABLE IF EXISTS B;</span><br><span class="line">CREATE TABLE B LIKE A;</span><br><span class="line">INSERT INTO B SELECT * FROM A;</span><br></pre></td></tr></table></figure>
<h3 id="导出备份单个表"><a href="#导出备份单个表" class="headerlink" title="导出备份单个表"></a>导出备份单个表</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysqldump -u root -p dbname tablename &gt; table.sql</span><br></pre></td></tr></table></figure>
<h3 id="导出备份整个库"><a href="#导出备份整个库" class="headerlink" title="导出备份整个库"></a>导出备份整个库</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysqldump -u root -p dbname &gt; db.sql</span><br></pre></td></tr></table></figure>
<h3 id="导入通过mysql命令"><a href="#导入通过mysql命令" class="headerlink" title="导入通过mysql命令"></a>导入通过mysql命令</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysql -u root -p vocabulary_enhancer_db &lt; /mysql_sql_temp/old_bak.sql</span><br></pre></td></tr></table></figure>
<h3 id="临时表备份"><a href="#临时表备份" class="headerlink" title="临时表备份"></a>临时表备份</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">CREATE TEMPORARY TABLE tmp_table SELECT * FROM table_name;</span><br></pre></td></tr></table></figure>
<h2 id="所有子查询都要用唯一别名"><a href="#所有子查询都要用唯一别名" class="headerlink" title="所有子查询都要用唯一别名"></a>所有子查询都要用唯一别名</h2><h2 id="主键插入返回"><a href="#主键插入返回" class="headerlink" title="主键插入返回"></a>主键插入返回</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&lt;insert id=&quot;genSequence&quot; parameterType=&quot;com.ccssoft.ngbip.sdk.core.entity.Sequence&quot;&gt;</span><br><span class="line">    insert into $&#123;tableName&#125; (stub) values (&apos;b&apos;)</span><br><span class="line">    &lt;selectKey resultType=&quot;integer&quot; keyProperty=&quot;id&quot;&gt;</span><br><span class="line">        select last_insert_id() as id</span><br><span class="line">        &lt;!-- select &apos;NEXT VALUE FOR MYCATSEQ_$&#123;tableName&#125;&apos; as id --&gt;</span><br><span class="line">    &lt;/selectKey&gt;</span><br><span class="line">&lt;/insert&gt;</span><br></pre></td></tr></table></figure>
<p><a href="https://blog.csdn.net/czd3355/article/details/71302441/" target="_blank" rel="noopener">https://blog.csdn.net/czd3355/article/details/71302441/</a></p>
<h1 id="表设计"><a href="#表设计" class="headerlink" title="表设计"></a>表设计</h1><h2 id="外键设计"><a href="#外键设计" class="headerlink" title="外键设计"></a>外键设计</h2><p>尽量避免使用外键，如果一定要使用外键的情况下，必须要考虑是否要在主表加上ON DELETE CASCADE或者ON UPDATE CASCADE，大部分情况下是必须要加上这个级联约束的，但是要注意的是，关系表中的外键，一定要建索引，否则在删除主键时级联删除外键会很慢很慢。</p>
<h2 id="主键使用uuid和自增int的区别"><a href="#主键使用uuid和自增int的区别" class="headerlink" title="主键使用uuid和自增int的区别"></a>主键使用uuid和自增int的区别</h2><p><a href="http://www.mysqltutorial.org/mysql-uuid/" target="_blank" rel="noopener">http://www.mysqltutorial.org/mysql-uuid/</a><br><a href="https://juejin.im/post/5c32a7a86fb9a049ad7734b3" target="_blank" rel="noopener">https://juejin.im/post/5c32a7a86fb9a049ad7734b3</a><br>最近在重构公司一个老的模块，重构当然要从数据库开始着手，关于数据表主键的实现方式选择，我想到的有二种方式，一种是uuid，一种是自增int，<br>先抛开是否分布式架构不说，选用uuid网上都会提到两个明显的弊端：<br>1、是数据暂用空间大.<br>2、数据无序性对索引这种树结构的存储有性能上的影响。</p>
<p>第一点我倒是觉得没什么大的影响，现在的硬盘已经不是缺那点点存储的问题了。<br>选用自增int的话，也有两个明显的弊端：<br>1、存在安全性问题，将一个已知主键加减某个值就得到另外一个主键了。<br>2、如果多个表数据合并，可以自增主键存在冲突。</p>
<p>真到了分布式的可以有第三方成熟的实现方案可供选择。<br>结论：尽量使用整型做主键，数据无序性的开销太大了，这点足以让整型的弊端再多，也必须竭力去解决弊端后选择整型做主键。</p>
<h2 id="主键int还是bigint"><a href="#主键int还是bigint" class="headerlink" title="主键int还是bigint"></a>主键int还是bigint</h2><p>int的范围：从 -2^31 (-2,147,483,648) 到 2^31 - 1 (2,147,483,647) 的整型数据（所有数字）。存储大小为 4 个字节。int 的 SQL-92 同义字为 integer。<br>bigint的范围：从 -2^63 (-9223372036854775808) 到 2^63-1 (9223372036854775807) 的整型数据（所有数字）。存储大小为 8 个字节。</p>
<p>int的上限已经很大了，一般的应用不会超出这个范围，所以主键一般使用int，也可以节省存储。</p>
<h2 id="分布式主键自增实现方案"><a href="#分布式主键自增实现方案" class="headerlink" title="分布式主键自增实现方案"></a>分布式主键自增实现方案</h2><p><a href="https://tech.meituan.com/2017/04/21/mt-leaf.html" target="_blank" rel="noopener">美团Leaf</a><br><a href="https://www.cnblogs.com/relucent/p/4955340.html" target="_blank" rel="noopener">twitter的snowflake</a></p>
<h2 id="创建和更新时间"><a href="#创建和更新时间" class="headerlink" title="创建和更新时间"></a>创建和更新时间</h2><p>必要时，尽量在表里面添加创建时间（create_time）和更新事件（update_time）</p>
<h2 id="表的DDL维护成本高，必要时可以考虑多留几个扩展字段备用"><a href="#表的DDL维护成本高，必要时可以考虑多留几个扩展字段备用" class="headerlink" title="表的DDL维护成本高，必要时可以考虑多留几个扩展字段备用"></a>表的DDL维护成本高，必要时可以考虑多留几个扩展字段备用</h2><p><a href="https://www.jianshu.com/p/47a1d7998fe0" target="_blank" rel="noopener">https://www.jianshu.com/p/47a1d7998fe0</a></p>
<h2 id="Mysql-的表尽量设置成-K-V-Key-Value-结构，什么情况下适合设计成K-V结构？"><a href="#Mysql-的表尽量设置成-K-V-Key-Value-结构，什么情况下适合设计成K-V结构？" class="headerlink" title="Mysql 的表尽量设置成 K-V (Key-Value) 结构，什么情况下适合设计成K-V结构？"></a>Mysql 的表尽量设置成 K-V (Key-Value) 结构，什么情况下适合设计成K-V结构？</h2><p><a href="https://blog.csdn.net/zcl_love_wx/article/details/81178339" target="_blank" rel="noopener">表Key-value结构介绍</a><br>在存储一些数据结构经常变动的数据适合采用K-V结构。</p>
<h2 id="为什么要尽量避免表字段为NULL值"><a href="#为什么要尽量避免表字段为NULL值" class="headerlink" title="为什么要尽量避免表字段为NULL值"></a>为什么要尽量避免表字段为NULL值</h2><p>表字段避免 null 值出现，null 值很难查询优化且占用额外的索引空间，推荐默认数字 0 代替 null。<br><img src="https://cdn.jsdelivr.net/gh/coding-by-feng/oss@master/uPic/43t5XR.png" alt></p>
<h2 id="字段类型的选择"><a href="#字段类型的选择" class="headerlink" title="字段类型的选择"></a>字段类型的选择</h2><ul>
<li>尽量使用 INT 而非 BIGINT，如果非负则加上 UNSIGNED（这样数值容量会扩大一倍），当然能使用 TINYINT、SMALLINT、MEDIUM_INT 更好。</li>
<li>使用整数代替字符串类型</li>
<li><a href="https://cloud.tencent.com/developer/news/155166" target="_blank" rel="noopener">枚举类型的弊端</a></li>
</ul>
<h2 id="IP使用整型来存储"><a href="#IP使用整型来存储" class="headerlink" title="IP使用整型来存储"></a>IP使用整型来存储</h2><p><a href="https://bafford.com/2009/03/09/mysql-performance-benefits-of-storing-integer-ip-addresses/" target="_blank" rel="noopener">为什么推荐使用</a><br>注意最后一段：<br>The load on MySQL when inserting integer IPs could likely be slightly reduced by doing that conversion in your application, rather than using MySQL’s INET_ATON() function.<br>ip的转换可以考虑放到应用程序来做，而不是通过Mysql的函数做转换。</p>
<h2 id="Mysql的分库分表，水平拆分-垂直拆分-todo"><a href="#Mysql的分库分表，水平拆分-垂直拆分-todo" class="headerlink" title="Mysql的分库分表，水平拆分-垂直拆分 todo"></a>Mysql的分库分表，水平拆分-垂直拆分 todo</h2><h2 id="共享表空间和独享表空间的区别和优缺点"><a href="#共享表空间和独享表空间的区别和优缺点" class="headerlink" title="共享表空间和独享表空间的区别和优缺点"></a>共享表空间和独享表空间的区别和优缺点</h2><p><a href="http://blog.itpub.net/15498/viewspace-2124040/" target="_blank" rel="noopener">http://blog.itpub.net/15498/viewspace-2124040/</a></p>
<h2 id="单表大小限制与表空间的关系"><a href="#单表大小限制与表空间的关系" class="headerlink" title="单表大小限制与表空间的关系"></a>单表大小限制与表空间的关系</h2><p><a href="https://blog.csdn.net/wsh900221/article/details/80242299" target="_blank" rel="noopener">https://blog.csdn.net/wsh900221/article/details/80242299</a></p>
<h2 id="timestamp-默认当前时间不能同时是not-null"><a href="#timestamp-默认当前时间不能同时是not-null" class="headerlink" title="timestamp 默认当前时间不能同时是not null"></a>timestamp 默认当前时间不能同时是not null</h2><h1 id="命名"><a href="#命名" class="headerlink" title="命名"></a>命名</h1><ul>
<li>索引使用_ind结尾，字段的多个单词取单词的首字母组合，例如：sample 表 member_id 上的索引:sample_mid_ind。</li>
<li>主键约束: pk 结尾，_pk;</li>
<li>unique 约束:_uk 结尾，uk;</li>
<li>check 约束: _ck 结尾，ck;</li>
<li>外键约束: _fk 结尾，以 pri 连接本表与主表，_pri_fk;</li>
<li>数据库表示是与否的值，使用 tinyint 类型，坚持 is_xxx 的 命名方式是为了明确其取值含义与取值范围;</li>
<li>表名、字段名必须使用小写字母或数字，禁止出现数字开头，禁止两个下划线中间只<br>出现数字。数据库字段名的修改代价很大，因为无法进行预发布，所以字段名称需要慎重考虑;</li>
</ul>
<h2 id="Mysql关键字大全"><a href="#Mysql关键字大全" class="headerlink" title="Mysql关键字大全"></a>Mysql关键字大全</h2><p><a href="https://blog.csdn.net/weixin_43201975/article/details/88953903" target="_blank" rel="noopener">https://blog.csdn.net/weixin_43201975/article/details/88953903</a></p>
<h1 id="约束"><a href="#约束" class="headerlink" title="约束"></a>约束</h1><h2 id="为什么推荐外键约束放在应用层，不在数据库库"><a href="#为什么推荐外键约束放在应用层，不在数据库库" class="headerlink" title="为什么推荐外键约束放在应用层，不在数据库库?"></a>为什么推荐外键约束放在应用层，不在数据库库?</h2><p><a href="https://learnku.com/articles/25116" target="_blank" rel="noopener">https://learnku.com/articles/25116</a></p>
<h1 id="索引"><a href="#索引" class="headerlink" title="索引"></a>索引</h1><ul>
<li>索引并不是越多越好，要根据查询有针对性的创建，考虑在 WHERE 和 ORDER BY 命令上涉及的列建立索引，可根据 EXPLAIN 来查看是否用了索引还是全表扫描</li>
<li>应尽量避免在 WHERE 子句中对字段进行 NULL 值判断，否则将导致引擎放弃使用索引而进行全表扫描</li>
<li>值分布很稀少的字段不适合建索引，例如 “性别” 这种只有两三个值的字段</li>
<li>字符字段太长的话，考虑用前缀索引</li>
<li>字符字段最好不要做主键 - 超过三个表禁止 join。需要 join 的字段，数据类型必须绝对一致;多表关联查询时， 保证被关联的字段需要有索引。(即使双表 join 也要注意表索引、SQL 性能)</li>
</ul>
<h2 id="前缀索引"><a href="#前缀索引" class="headerlink" title="前缀索引"></a>前缀索引</h2><p><a href="https://blog.csdn.net/ma2595162349/article/details/79449493" target="_blank" rel="noopener">前缀索引解释</a><br>如果是对已经存在的表建前缀索引，要先去比较重复率再择优创建索引：<br><img src="https://cdn.jsdelivr.net/gh/coding-by-feng/oss@master/uPic/l55Uqw.png" alt></p>
<h2 id="联合索引之最左原则（左前缀原则）"><a href="#联合索引之最左原则（左前缀原则）" class="headerlink" title="联合索引之最左原则（左前缀原则）"></a>联合索引之最左原则（左前缀原则）</h2><p><a href="https://blog.csdn.net/wdjxxl/article/details/79790421" target="_blank" rel="noopener">https://blog.csdn.net/wdjxxl/article/details/79790421</a><br><a href="https://blog.csdn.net/Wuhaotian1996/article/details/80469353" target="_blank" rel="noopener">https://blog.csdn.net/Wuhaotian1996/article/details/80469353</a></p>
<h2 id="多对多的关联表索引"><a href="#多对多的关联表索引" class="headerlink" title="多对多的关联表索引"></a>多对多的关联表索引</h2><p>一般是在二个关联的主键字典建唯一联合索引，避免重复数据，提升查询效率。</p>
<h2 id="覆盖索引"><a href="#覆盖索引" class="headerlink" title="覆盖索引"></a>覆盖索引</h2><p>Order by的时候，如果一个索引包含(或覆盖)所有需要查询的字段的值，称为‘覆盖索引’。即只需扫描索引而无须扫表。</p>
<h2 id="order-by出现file-sort"><a href="#order-by出现file-sort" class="headerlink" title="order by出现file_sort"></a>order by出现file_sort</h2><p><a href="https://dev.mysql.com/doc/refman/8.0/en/order-by-optimization.html" target="_blank" rel="noopener">order by 官方的优化文档</a><br><a href="https://www.cnblogs.com/developer_chan/p/9225638.html" target="_blank" rel="noopener">Order by 优化</a><br>没有使用到索引来排序是，执行计划会显示file_sort。<br>需要重点注意的是，索引创建是也是有排序的，默认是ASC，如果Order by的排序和索引创建的时候指定的不一致，也会导致file_sort。  </p>
<p>非联合索引不受order by后面的升序和降序影响到是否使用索引排序，联合索引的情况下应该考虑order  by的升序降序是否和索引创建时一致。</p>
<h2 id="时间类字段是否应该建索引"><a href="#时间类字段是否应该建索引" class="headerlink" title="时间类字段是否应该建索引"></a>时间类字段是否应该建索引</h2><p>我自己测试了一下建索引确实是性能上有明显提升的，<br>没加索引：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[2019-12-25 15:13:59] 1 row retrieved starting from 1 in 592 ms (execution: 576 ms, fetching: 16 ms)</span><br></pre></td></tr></table></figure></p>
<p><img src="https://cdn.jsdelivr.net/gh/coding-by-feng/oss@master/uPic/l55Uqw.png" alt><br>加上索引之后：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[2019-12-25 15:19:28] 1 row retrieved starting from 1 in 258 ms (execution: 239 ms, fetching: 19 ms)</span><br></pre></td></tr></table></figure></p>
<p><img src="https://cdn.jsdelivr.net/gh/coding-by-feng/oss@master/uPic/otmOCJ.png" alt></p>
<h2 id="什么情况下SQL不会使用到索引"><a href="#什么情况下SQL不会使用到索引" class="headerlink" title="什么情况下SQL不会使用到索引"></a>什么情况下SQL不会使用到索引</h2><ul>
<li>like出现左匹配：’%XXX’</li>
<li>where语句中使用&lt;&gt;, !=, not in</li>
<li>where语句中使用 or，但是没有把or中所有字段加上索引，这种情况，如果需要使用索引需要将or中所有的字段都加上索引。</li>
<li>where语句中对字段表达式操作</li>
<li>使用索引的时候没有遵从索引的左前缀原则</li>
</ul>
<h2 id="SQL编写优化"><a href="#SQL编写优化" class="headerlink" title="SQL编写优化"></a>SQL编写优化</h2><ul>
<li>避免 select <em>，将需要查找的字段列出来，这里并不是因为select </em> 就一定是性能明显更差的原因，具体解释参考<a href="https://blog.csdn.net/qq_38836118/article/details/88708933" target="_blank" rel="noopener">https://blog.csdn.net/qq_38836118/article/details/88708933</a></li>
</ul>
<h2 id="SQL手工拼写的防止注入"><a href="#SQL手工拼写的防止注入" class="headerlink" title="SQL手工拼写的防止注入"></a>SQL手工拼写的防止注入</h2><p>varchar类型的字段，在拼写条件值得时候，外面用单引号包围起来，如：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">+ objId + &quot; and o.disp_object_type=&apos;&quot; + objType + &quot;&apos;&quot;);</span><br></pre></td></tr></table></figure></p>
<h1 id="Problem-Solution"><a href="#Problem-Solution" class="headerlink" title="Problem Solution"></a>Problem Solution</h1><h2 id="The-last-packet-sent-successfully-to-the-server-was-0-milliseconds-ago-The-driver-has-not-received-any-packets-from-the-server"><a href="#The-last-packet-sent-successfully-to-the-server-was-0-milliseconds-ago-The-driver-has-not-received-any-packets-from-the-server" class="headerlink" title="The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server."></a>The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.</h2><p>自己出现这个问题是因为连公司内部库是用vpn，vpn连续开了2天，连接mysql就报了这个错，vpn重启一下就ok了。</p>
<h2 id="required-a-bean-of-type-‘org-springframework-cache-CacheManager’-that-could-not-be-found"><a href="#required-a-bean-of-type-‘org-springframework-cache-CacheManager’-that-could-not-be-found" class="headerlink" title="required a bean of type ‘org.springframework.cache.CacheManager’ that could not be found."></a>required a bean of type ‘org.springframework.cache.CacheManager’ that could not be found.</h2><p>需要再spring.foctories添加org.springframework.boot.autoconfigure.EnableAutoConfiguration配置，<br>至少需要配置RedisTemplate</p>
<h2 id="ERROR-2002-HY000-Can’t-connect-to-local-MySQL-server-through-socket-‘-tmp-mysql-sock’-111"><a href="#ERROR-2002-HY000-Can’t-connect-to-local-MySQL-server-through-socket-‘-tmp-mysql-sock’-111" class="headerlink" title="ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’ (111)"></a>ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’ (111)</h2><p>可能是数据库服务资源紧张挂掉了，mysqld进程我已查看都不在了，重启mysql就好了，当然也有其他原因也会导致这个报错。</p>
<h2 id="delete语句子查询not-exists是不会生效的"><a href="#delete语句子查询not-exists是不会生效的" class="headerlink" title="delete语句子查询not exists是不会生效的"></a>delete语句子查询not exists是不会生效的</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">delete</span><br><span class="line">from word_paraphrase_star_rel</span><br><span class="line">where not exists(select * from word_paraphrase wp where wp.paraphrase_id = paraphrase_id);</span><br></pre></td></tr></table></figure>
<p>需要改成：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">delete</span><br><span class="line">from word_paraphrase_star_rel</span><br><span class="line">where paraphrase_id in (select tmp.paraphrase_id</span><br><span class="line">                        from (select wpsr.paraphrase_id</span><br><span class="line">                              from word_paraphrase_star_rel wpsr</span><br><span class="line">                              where not exists(</span><br><span class="line">                                      select *</span><br><span class="line">                                      from word_paraphrase wp</span><br><span class="line">                                      where wp.paraphrase_id = wpsr.paraphrase_id)) tmp)</span><br></pre></td></tr></table></figure></p>
<h2 id="You-can’t-specify-target-table-‘word-paraphrase-star-rel’-for-update-in-FROM-clause"><a href="#You-can’t-specify-target-table-‘word-paraphrase-star-rel’-for-update-in-FROM-clause" class="headerlink" title="You can’t specify target table ‘word_paraphrase_star_rel’ for update in FROM clause"></a>You can’t specify target table ‘word_paraphrase_star_rel’ for update in FROM clause</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">delete</span><br><span class="line">from word_paraphrase_star_rel</span><br><span class="line">where paraphrase_id in (select wpsr.paraphrase_id</span><br><span class="line">                        from word_paraphrase_star_rel wpsr</span><br><span class="line">                        where not exists(</span><br><span class="line">                                select * from word_paraphrase wp where wp.paraphrase_id = wpsr.paraphrase_id))</span><br></pre></td></tr></table></figure>
<p>改成下面即可：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">delete</span><br><span class="line">from word_paraphrase_star_rel</span><br><span class="line">where paraphrase_id in (select tmp.paraphrase_id</span><br><span class="line">                        from (select wpsr.paraphrase_id</span><br><span class="line">                              from word_paraphrase_star_rel wpsr</span><br><span class="line">                              where not exists(</span><br><span class="line">                                      select *</span><br><span class="line">                                      from word_paraphrase wp</span><br><span class="line">                                      where wp.paraphrase_id = wpsr.paraphrase_id)) tmp)</span><br></pre></td></tr></table></figure></p>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-Hans">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2019/12/01/Idea汇总/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="Fengorz">
      <meta itemprop="description" content="A Quiet Departure.">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Feng's Blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/2019/12/01/Idea汇总/" class="post-title-link" itemprop="url">Idea汇总</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2019-12-01 21:10:40" itemprop="dateCreated datePublished" datetime="2019-12-01T21:10:40+08:00">2019-12-01</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2020-07-30 10:48:35" itemprop="dateModified" datetime="2020-07-30T10:48:35+08:00">2020-07-30</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">In</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Idea/" itemprop="url" rel="index"><span itemprop="name">Idea</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <blockquote>
<p>有部分内容来自网络，一般都有注明出处，如若侵权，请联系我删除，谢谢！<br>文章的图片来自github的图床，图片链接存在github图床（<a href="https://raw.githubusercontent.com），该地址可能需要翻墙才能访问，所以图片可能存在加载不成功的情况。" target="_blank" rel="noopener">https://raw.githubusercontent.com），该地址可能需要翻墙才能访问，所以图片可能存在加载不成功的情况。</a></p>
</blockquote>
<h1 id="HOTKEY"><a href="#HOTKEY" class="headerlink" title="HOTKEY"></a>HOTKEY</h1><h2 id="Usage-Search（使用查询）"><a href="#Usage-Search（使用查询）" class="headerlink" title="Usage Search（使用查询）"></a>Usage Search（使用查询）</h2><table>
<thead>
<tr>
<th>key</th>
<th>desc</th>
</tr>
</thead>
<tbody>
<tr>
<td>cmd+opt+F7</td>
<td>搜索文件中用法，以弹窗方式显示</td>
</tr>
<tr>
<td>opt+F7</td>
<td>全局搜索引用</td>
</tr>
<tr>
<td>cmd+shift+F7</td>
<td>高亮显示当前代码域使用到的地方</td>
</tr>
<tr>
<td>F3 or shift+F3</td>
<td>搜索当前文件的模式下，按向下 or F3跳到下一处，按向上 or shift+F3跳到上一处</td>
</tr>
<tr>
<td>tab or tab+shift</td>
<td>在ctrl+shift+f全局搜索的时候，可以通过tab和来移动输入聚焦，可以脱离鼠标来选择右上角的File mask</td>
</tr>
</tbody>
</table>
<h2 id="Editing（编辑）"><a href="#Editing（编辑）" class="headerlink" title="Editing（编辑）"></a>Editing（编辑）</h2><table>
<thead>
<tr>
<th>key</th>
<th>desc</th>
</tr>
</thead>
<tbody>
<tr>
<td>cmd+P</td>
<td>显示方法的参数，这个方法的强大之处在于，展示了参数之后，在写入传参的时候，弹框会一直存在，让参数更加直观</td>
</tr>
<tr>
<td>cmd++</td>
<td>展开折叠的代码</td>
</tr>
<tr>
<td>cmd+-</td>
<td>折叠代码</td>
</tr>
<tr>
<td>shift+上下方向键</td>
<td>有时候用vim插件的jk上下移动太慢了，而且又不能明确知道要用emacsIdeas调整到哪里，可以用idea自带的shift+上下方向键来快速上下移动代码</td>
</tr>
</tbody>
</table>
<h2 id="debug"><a href="#debug" class="headerlink" title="debug"></a>debug</h2><table>
<thead>
<tr>
<th>key</th>
<th>desc</th>
</tr>
</thead>
<tbody>
<tr>
<td>cmd+shift+F8</td>
<td>查看断点信息</td>
</tr>
<tr>
<td>shift+F7</td>
<td>智能步入，断点所在行上有多个方法调用，会弹出进入哪个方法</td>
</tr>
<tr>
<td>^+F5</td>
<td>重启debug服务</td>
</tr>
<tr>
<td>cmd+F2</td>
<td>终止debug服务</td>
</tr>
<tr>
<td>^+cmd+W</td>
<td>将Add to Watches绑定快捷键，可以快速查看变量或者表达式的值</td>
</tr>
</tbody>
</table>
<h2 id="Spring-Boot-微服务"><a href="#Spring-Boot-微服务" class="headerlink" title="Spring Boot 微服务"></a>Spring Boot 微服务</h2><p>cmd+8 弹出多个微服务的启动控制窗口，可以通过上下左右移动快速定位到某个微服务，通过快捷键^+shiftF10 Runing,或者通过^+shift+F9 Debuging</p>
<h2 id="General（通用）"><a href="#General（通用）" class="headerlink" title="General（通用）"></a>General（通用）</h2><table>
<thead>
<tr>
<th>key</th>
<th>desc</th>
</tr>
</thead>
<tbody>
<tr>
<td>^+cmd+F</td>
<td>切换全屏模式</td>
</tr>
<tr>
<td>^+cmd+C</td>
<td>清理控制台的日志之类的，需要再keymap里面设置Other</td>
<td>Clear All</td>
</tr>
</tbody>
</table>
<h2 id="Refactoring（重构）"><a href="#Refactoring（重构）" class="headerlink" title="Refactoring（重构）"></a>Refactoring（重构）</h2><table>
<thead>
<tr>
<th>key</th>
<th>desc</th>
</tr>
</thead>
<tbody>
<tr>
<td>F5</td>
<td>复制文件到指定包路径</td>
</tr>
<tr>
<td>F6</td>
<td>移动文件到指定包路径</td>
</tr>
<tr>
<td>opt+cmd+t</td>
<td>surround with 快捷得用各种模板语法包括代码（这个很强大`）</td>
</tr>
<tr>
<td>opt+cmd+m</td>
<td>提取代码为方法</td>
</tr>
<tr>
<td>opt+cmd+c</td>
<td>提出代码为常量</td>
</tr>
<tr>
<td>opt+cmd+v</td>
<td>提出代码为变量</td>
</tr>
<tr>
<td>opt+cmd+f</td>
<td>提出代码为成员变量</td>
</tr>
<tr>
<td>opt+cmd+p</td>
<td>提出代码为方法的形参</td>
</tr>
<tr>
<td>opt+cmd+o</td>
<td>快速去掉多余的import</td>
</tr>
</tbody>
</table>
<h2 id="Navigation（导航）"><a href="#Navigation（导航）" class="headerlink" title="Navigation（导航）"></a>Navigation（导航）</h2><table>
<thead>
<tr>
<th>key</th>
<th>desc</th>
</tr>
</thead>
<tbody>
<tr>
<td>alt+F1</td>
<td>跳转到当前代码文件很多相关的功能（强大）</td>
</tr>
<tr>
<td>cmd+u</td>
<td>前往当前光标所在方法的父类的方法 / 接口定义</td>
</tr>
<tr>
<td>cmd+b</td>
<td>进入定义处</td>
</tr>
<tr>
<td>cmd+opt+b</td>
<td>进入实现处</td>
</tr>
<tr>
<td>cmd+o</td>
<td>查询当前类可以继承实现的所有方法</td>
</tr>
<tr>
<td>cmd+F12</td>
<td>展示当前文件的结果大纲（可用于查询变量、方法等）</td>
</tr>
<tr>
<td>^+shift+B</td>
<td>跳转到类型声明处，可以直接从类变量跳到对应的类里面</td>
</tr>
<tr>
<td>F12</td>
<td>返回前一个工具窗口</td>
</tr>
<tr>
<td>shift+esc</td>
<td>隐藏当前或最后一个活动的窗口，且光标进入代码文件窗口</td>
</tr>
<tr>
<td>opt+F1</td>
<td>显示当前文件选择目标弹出层，弹出层中有很多目标可以进行选择（如在代码编辑窗口可以选择显示该文件的 Finder）</td>
</tr>
<tr>
<td>⌃H</td>
<td>显示当前类的层次结构(在类的任何地方可以快速跳转到父类、父接口、子类)</td>
</tr>
<tr>
<td>^+opt+H</td>
<td>显示所有调用的层次结构</td>
</tr>
<tr>
<td>^+h</td>
<td>显示类的所有子类型的相关内容</td>
</tr>
<tr>
<td>shift+F4</td>
<td>在新窗口打开文件</td>
</tr>
<tr>
<td>^+F2</td>
<td>可以快速跳到idea的菜单栏，然后通过方向键和enter，可以快速进行一下菜单栏的操作，这个快捷键适合其他软件</td>
</tr>
<tr>
<td>^+opt+cmd+N</td>
<td>跳到next method，这个是我自定义的</td>
</tr>
<tr>
<td>^+opt+cmd+P</td>
<td>跳到previous method，这个是我自定义的</td>
</tr>
<tr>
<td>跳到光标所在方法的方法名</td>
<td>先^+opt+cmd+N再^+opt+cmd+P，如果是最后一个方法就反之</td>
</tr>
</tbody>
</table>
<h2 id="后缀补全"><a href="#后缀补全" class="headerlink" title="后缀补全"></a>后缀补全</h2><h3 id="var"><a href="#var" class="headerlink" title="var"></a>var</h3><p>声明变量或者调用方法之后输入<code>.var</code>，可以自动生成前面的变量声明</p>
<h3 id="null"><a href="#null" class="headerlink" title="null"></a>null</h3><p>某个变量或者表达式之后输入<code>.null</code>，自动生成if空判断</p>
<h3 id="nn"><a href="#nn" class="headerlink" title="nn"></a>nn</h3><p>某个变量或者表达式之后输入<code>.nn</code>，自动生成if不为空判断</p>
<h3 id="not"><a href="#not" class="headerlink" title="not"></a>not</h3><p>某个变量或者表达式之后输入<code>.not</code>，自动生成取反</p>
<h3 id="还有for、return、if、opt等等常用的"><a href="#还有for、return、if、opt等等常用的" class="headerlink" title="还有for、return、if、opt等等常用的"></a>还有for、return、if、opt等等常用的</h3><h1 id="PLUGIN-插件"><a href="#PLUGIN-插件" class="headerlink" title="PLUGIN(插件)"></a>PLUGIN(插件)</h1><h2 id="emacsIdeas-最强大没有之一"><a href="#emacsIdeas-最强大没有之一" class="headerlink" title="emacsIdeas 最强大没有之一"></a>emacsIdeas 最强大没有之一</h2><blockquote>
<p>注意如果和IdeaVim一同使用的话，类似^+W的快捷键要更改，不然会和IdeaVim的屏幕分割快捷键冲突了</p>
</blockquote>
<h4 id="jump"><a href="#jump" class="headerlink" title="jump"></a>jump</h4><ul>
<li>Plug-ins | emacsIDEAs | AceJumpSelect       选中当前位置到某个字符</li>
<li>Plug-ins | emacsIDEAs | HighlightPrevSymbol 高亮跳到上一个一样的字符</li>
<li>Plug-ins | emacsIDEAs | HighlightNextSymbol 高亮跳到下一个一样的字符</li>
</ul>
<h4 id="emacsIdeas-copy"><a href="#emacsIdeas-copy" class="headerlink" title="emacsIdeas copy"></a>emacsIdeas copy</h4><ul>
<li>Plug-ins | emacsIDEAs | AceJumpCopy.Block       复制特定代码块到当前光标(可以是函数里面的整个形参定义)</li>
<li>Plug-ins | emacsIDEAs | AceJumpCopy.Line        复制特定行到当前光标</li>
<li>Plug-ins | emacsIDEAs | AceJumpCopy.Quote       复制特定的引用到当前光标，比如某个引号里面的内容</li>
<li>Plug-ins | emacsIDEAs | AceJumpCopy.String      复制特定的代码到当前光标，一般是某块前后由空格隔开的代码</li>
<li>Plug-ins | emacsIDEAs | AceJumpCopy.ToLineEnd   从当前位置复制到行尾</li>
<li>Plug-ins | emacsIDEAs | AceJumpCopy.ToLineStart 从当前位置复制到行首</li>
<li>Plug-ins | emacsIDEAs | AceJumpCopy.Paragraph   复制某个特定段落，比如类的某段注释</li>
<li>Plug-ins | emacsIDEAs | AceJumpCopy.Group       复制某块代码，可以使某个判断的条件+整个花括号{}里面的内容 </li>
</ul>
<h4 id="emacsIdeas-delete"><a href="#emacsIdeas-delete" class="headerlink" title="emacsIdeas delete"></a>emacsIdeas delete</h4><ul>
<li>Plug-ins | emacsIDEAs | AceJumpCut                  从当前位置剪切到某个位置</li>
<li>Plug-ins | emacsIDEAs | AceJumpDelete.Block         删除特定的代码块 </li>
<li>Plug-ins | emacsIDEAs | AceJumpDelete.Line          删除特定的代码行</li>
<li>Plug-ins | emacsIDEAs | AceJumpDelete.Quote         删除特定的引用代码，比如某个引号里面的内容</li>
<li>Plug-ins | emacsIDEAs | AceJumpDelete.String        删除特定的二个空格之间的字符 </li>
<li>Plug-ins | emacsIDEAs | AceJumpDelete.Word          删除特定的某个变量方法名（紧挨在一起的代码标识）</li>
<li>Plug-ins | emacsIDEAs | AceJumpDelete.ToLineEnd     从当前位置删除到行尾</li>
<li>Plug-ins | emacsIDEAs | AceJumpDelete.ToLineStart   从当前位置删除到行首</li>
<li>Plug-ins | emacsIDEAs | AceJumpDelete.Paragraph     删除某个特定段落，比如类的某段注释</li>
</ul>
<h4 id="emacsIdeas-cut"><a href="#emacsIdeas-cut" class="headerlink" title="emacsIdeas cut"></a>emacsIdeas cut</h4><ul>
<li>Plug-ins | emacsIDEAs | AceJumpCut  从光标当前位置剪切到某个位置</li>
</ul>
<h4 id="emacsIdeas-more"><a href="#emacsIdeas-more" class="headerlink" title="emacsIdeas more"></a>emacsIdeas more</h4><p>AceJumpMove模式，各种快捷键的变种和上面的一样.etc.</p>
<h2 id="ideaVim"><a href="#ideaVim" class="headerlink" title="ideaVim"></a>ideaVim</h2><p>yy 复制当值当前行，或者选中后y复制，然后输入数字n，再输入p，代表连续粘贴n次。<br>gg 快速移动到文件的开头<br>G  快速移动到文件的结尾</p>
<h2 id="CamelCase"><a href="#CamelCase" class="headerlink" title="CamelCase"></a>CamelCase</h2><p>opt+shift+u 可以对字符进行驼峰式的不同格式变换，非常实用。</p>
<h2 id="Grep-Console"><a href="#Grep-Console" class="headerlink" title="Grep Console"></a>Grep Console</h2><p>安装该日志插件，控制台的日志输出可以更加直观，还可以自定义颜色。</p>
<h2 id="spring-assistant-yml或者properties文件编写提示"><a href="#spring-assistant-yml或者properties文件编写提示" class="headerlink" title="spring assistant(yml或者properties文件编写提示)"></a>spring assistant(yml或者properties文件编写提示)</h2><p>编写yml配置文件的时候，可以自动提示，但是这个自动提示貌似自会提示Spring Boot的基础配置，如果是在配置中心的话，其他的第三方依赖配置要在配置中心引入其spring-boot-starter的依赖才能自动提示对应的配置。</p>
<p><strong><em>如果对应的依赖引入了之后还不会自动提示，那就需要再idea的模块配置里面将自定义的配置文件加入到配置文件的类别中，如下图:</em></strong><br><img src="https://cdn.jsdelivr.net/gh/coding-by-feng/oss@master/uPic/EpjOSE.png" alt><br>选择右边的第一个Configuration Files，因为通常配置中心新增的都不会是Bootstrap类别的配置文件，如下图，然后点击下面的绿色按钮，也就是最后一个按钮<br><img src="https://cdn.jsdelivr.net/gh/coding-by-feng/oss@master/uPic/RWKXhb.png" alt><br>再点击下面的+号，选择对一个的yml或者properties，然后确认就ok了。</p>
<h2 id="RestfulToolkit"><a href="#RestfulToolkit" class="headerlink" title="RestfulToolkit"></a>RestfulToolkit</h2><p>这个插件可以自动收集项目的Restful风格的接口，还可以在idea里面直接填写参数调用接口</p>
<h2 id="MyBatis-Log-Plugin"><a href="#MyBatis-Log-Plugin" class="headerlink" title="MyBatis Log Plugin"></a>MyBatis Log Plugin</h2><p>自动打印Mybatis的每一个SQL，有时候我们要抽取SQL不是很方便</p>
<h2 id="Free-Mybatis-plugin"><a href="#Free-Mybatis-plugin" class="headerlink" title="Free Mybatis plugin"></a>Free Mybatis plugin</h2><p>Mapper与Mapper XML映射之间的调整，方便代码的跟踪查看。<br>而且还可以自动通过Mapper的方法矫正或者生成Mapper.xml的每个xml节点</p>
<h2 id="ignore（版本控制忽略文件的好插件）支持各种文件忽略的配置"><a href="#ignore（版本控制忽略文件的好插件）支持各种文件忽略的配置" class="headerlink" title=".ignore（版本控制忽略文件的好插件）支持各种文件忽略的配置"></a>.ignore（版本控制忽略文件的好插件）支持各种文件忽略的配置</h2><p><a href="https://blog.csdn.net/byy8023/article/details/82259155" target="_blank" rel="noopener">https://blog.csdn.net/byy8023/article/details/82259155</a></p>
<h3 id="可以根据项目的引用的构建工具能来针对性忽略"><a href="#可以根据项目的引用的构建工具能来针对性忽略" class="headerlink" title="可以根据项目的引用的构建工具能来针对性忽略"></a>可以根据项目的引用的构建工具能来针对性忽略</h3><p><img src="https://cdn.jsdelivr.net/gh/coding-by-feng/oss@master/uPic/A8xyJA.png" alt><br>比如我的项目选择了JetBrains、MacOS、Java、Maven、Example user template</p>
<h3 id="如果出现-gitgnore忽略了某些要被纳入版本控制的文件或目录比如："><a href="#如果出现-gitgnore忽略了某些要被纳入版本控制的文件或目录比如：" class="headerlink" title="如果出现.gitgnore忽略了某些要被纳入版本控制的文件或目录比如："></a>如果出现.gitgnore忽略了某些要被纳入版本控制的文件或目录比如：</h3><p><img src="https://cdn.jsdelivr.net/gh/coding-by-feng/oss@master/uPic/rXGSPh.png" alt><br>直接删除掉想要重新纳入版本控制的目录或文件即可</p>
<h3 id="maven的target反复被纳入版本控制"><a href="#maven的target反复被纳入版本控制" class="headerlink" title="maven的target反复被纳入版本控制"></a>maven的target反复被纳入版本控制</h3><p>这个是因为之前target目录已经被版本控制了，需要先关闭idea的自动编译，然后mvn clean一下，再提交所有删除的target文件，然后恢复自动编译配置。</p>
<p>前提是.gitignore文件里面配置了Maven的忽略目录</p>
<h2 id="JUnitGenerator-V2-0"><a href="#JUnitGenerator-V2-0" class="headerlink" title="JUnitGenerator V2.0"></a>JUnitGenerator V2.0</h2><p>选中代码中的类名，按cmd+shift+T，可以生成自定义测试类。<br><a href="https://blog.51cto.com/12066352/2134091" target="_blank" rel="noopener">https://blog.51cto.com/12066352/2134091</a></p>
<h2 id="jclasslib-Bytecode-viewer"><a href="#jclasslib-Bytecode-viewer" class="headerlink" title="jclasslib Bytecode viewer"></a>jclasslib Bytecode viewer</h2><p>查看分析字节码的插件</p>
<h1 id="Others-其他"><a href="#Others-其他" class="headerlink" title="Others(其他)"></a>Others(其他)</h1><h2 id="修改包名要注意的地方"><a href="#修改包名要注意的地方" class="headerlink" title="修改包名要注意的地方"></a>修改包名要注意的地方</h2><p>修改了包名之后注意在编译输出的目录要清空之前的老的class，不然可能会引起意想不到的冲突。</p>
<h2 id="有没有更加智能化的API注释查看方法，比如鼠标-cmd的方式就完整地将注释都展示出来？"><a href="#有没有更加智能化的API注释查看方法，比如鼠标-cmd的方式就完整地将注释都展示出来？" class="headerlink" title="有没有更加智能化的API注释查看方法，比如鼠标+cmd的方式就完整地将注释都展示出来？"></a>有没有更加智能化的API注释查看方法，比如鼠标+cmd的方式就完整地将注释都展示出来？</h2><p>ctrl+J<br>可以搜索keymap需改热键，Quick Documentation</p>
<h2 id="debug的时候变量的多种不同的View"><a href="#debug的时候变量的多种不同的View" class="headerlink" title="debug的时候变量的多种不同的View"></a>debug的时候变量的多种不同的View</h2><p>在Variables右键要跟踪的变量,可以view text，或者view as 其他类型.</p>
<h2 id="Performance-enhancements（性能增加）"><a href="#Performance-enhancements（性能增加）" class="headerlink" title="Performance enhancements（性能增加）"></a>Performance enhancements（性能增加）</h2><p>idea吃内存确实是有点恐怖，对于调大内存，网上基本都是说调整idea.vmoptions里面的这三个参数：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">-Xms1024m</span><br><span class="line">-Xmx3000m</span><br><span class="line">-XX:ReservedCodeCacheSize=1024m</span><br></pre></td></tr></table></figure></p>
<p>但是我自己是基于2019.02的版本，发现即使调整了之后重启，idea右下角的内存显示还是原来的Max。<br>其实要这样调整才能真正生效：<br>Help-&gt;Edit Custom VM Options<br>打开这个会发现里面的配置还是原来的，在这里更改再重启，右下角的内存Max才会变大，才能生效。</p>
<h2 id="cmd-shift-A按第二次的时候老是换出Terminal"><a href="#cmd-shift-A按第二次的时候老是换出Terminal" class="headerlink" title="cmd+shift+A按第二次的时候老是换出Terminal"></a>cmd+shift+A按第二次的时候老是换出Terminal</h2><p><a href="https://intellij-support.jetbrains.com/hc/en-us/articles/360005137400-Cmd-Shift-A-hotkey-opens-Terminal-with-apropos-search-instead-of-the-Find-Action-dialog" target="_blank" rel="noopener">https://intellij-support.jetbrains.com/hc/en-us/articles/360005137400-Cmd-Shift-A-hotkey-opens-Terminal-with-apropos-search-instead-of-the-Find-Action-dialog</a></p>
<h2 id="Bug"><a href="#Bug" class="headerlink" title="Bug"></a>Bug</h2><p>有时候会出现复制进来的新文件编译之后没有被输出到target对应的目录，应该是idea潜在的bug，如果点击重新加载文件索引太慢了，一般重启一下重新编译可以解决。</p>
<h2 id="search（搜索）"><a href="#search（搜索）" class="headerlink" title="search（搜索）"></a>search（搜索）</h2><p>全局搜索的时候记得利用好Scope，比如要搜索某个模块，某所最近更改的内容，搜索版本控制的所有更改等等。</p>
<h2 id="Services"><a href="#Services" class="headerlink" title="Services"></a>Services</h2><p>cmd+8可以将多个SpringBoot的服务（微服务）整一个打开控制，可以结合其他快捷键进行启动、重启和停止，不过第一次使用需要再右下角的弹框中点击确认。<br>此外在Spring Cloud多个微服务的情况下，还可以将不同的微服务分组然后统一对某个组别进行run、debug或者静默断点等操作。</p>
<h2 id="使用lombok跟踪bean属性调用栈"><a href="#使用lombok跟踪bean属性调用栈" class="headerlink" title="使用lombok跟踪bean属性调用栈"></a>使用lombok跟踪bean属性调用栈</h2><p>opt+F7依然可以看到getter和setter的调用栈。</p>
<h2 id="SpringBoot-Application的热加载"><a href="#SpringBoot-Application的热加载" class="headerlink" title="SpringBoot Application的热加载"></a>SpringBoot Application的热加载</h2><p>要在debug模式下，设置Hot swap classes and update trigger file if failed，就可以自动热加载class了。</p>
<h2 id="idea的svn的删除操作"><a href="#idea的svn的删除操作" class="headerlink" title="idea的svn的删除操作"></a>idea的svn的删除操作</h2><p>本地删除之后要在，Locally Deleted Files中点击Remove from VCS，然后再回来上面的Default Changelist去执行Commit删除。</p>
<h2 id="折叠显示文件"><a href="#折叠显示文件" class="headerlink" title="折叠显示文件"></a>折叠显示文件</h2><p>可以在设置中搜索Soft-Wrap，根据文件格式配置是否折叠显示超过屏幕的行，也可以通过快捷键绑定折叠当前文件。<br><img src="https://cdn.jsdelivr.net/gh/coding-by-feng/oss@master/uPic/dPTK3g.png" alt></p>
<h2 id="提交代码前要先Optimize-Imports一下"><a href="#提交代码前要先Optimize-Imports一下" class="headerlink" title="提交代码前要先Optimize Imports一下"></a>提交代码前要先Optimize Imports一下</h2><p>可以cmd+9，在Default Changelist上Optimize Imports（opt+cmd+O）,这样就不会优化到其他没有修改到的代码，只操作自己改过的代码。</p>
<h2 id="Run-Debug-Configurations中Build和Build-Project的区别"><a href="#Run-Debug-Configurations中Build和Build-Project的区别" class="headerlink" title="Run/Debug Configurations中Build和Build Project的区别"></a>Run/Debug Configurations中Build和Build Project的区别</h2><p><img src="https://cdn.jsdelivr.net/gh/coding-by-feng/oss@master/uPic/sSnMvO.png" alt><br>Build只会编译配置依赖的模块，Build Project会编译模块依赖的所有项目，将编译器交给Maven代工的话注意要选择Build Project。</p>
<h1 id="all-shortcut"><a href="#all-shortcut" class="headerlink" title="all shortcut"></a>all shortcut</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">新建文件的时候可以这样操作来脱离鼠标：</span><br><span class="line">cmd+1跳到Project目录上下移动到目标目录，然后cmd+shift+A跳出Action，输入new+文件类型或者手动选择文件类型就可以了。</span><br></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line">option+cmd+c 抽取局部字符串为静态变量</span><br><span class="line">cmd+shift+方向键  可以控制模态框的大小，和左右移动编辑区的内容</span><br><span class="line">ctrl+j  展示API文档</span><br><span class="line">ctrl+shift+F,[words 打钩可以搜索是否为单词]</span><br><span class="line">command+D,</span><br><span class="line">commond+F12(file structure)</span><br><span class="line">command+shift+N(search file&apos;s name and global)</span><br><span class="line">commond+option+shift+N(search method d variable global)</span><br><span class="line">shirt + option + (向上箭头)/（向下箭头）(move codes up or down)</span><br><span class="line">Command + Option + L(Format code)</span><br><span class="line">option+enter（add javadoc）</span><br><span class="line">option+command+b(jump into the class impl)</span><br><span class="line">command+e(recent file)</span><br><span class="line">command+shift+a(search action)</span><br><span class="line">command+number(window tab jump)</span><br><span class="line">shift(ctrl)+command+del(last(next) edit location)</span><br><span class="line">F11，command+F11，ctrl+number(alphabet)(bookmarks)</span><br><span class="line">option+shift+F(add to favorites)</span><br><span class="line">shift+option+U(toggle case)</span><br><span class="line">command+1,esc(switch between file navigate and edit area)</span><br><span class="line">option+F7(find usage)</span><br><span class="line">shift+option+方向(move caret to next word)</span><br><span class="line">command+方向(move to first or end of line)</span><br><span class="line">ctrl+command+G(sellect all occurrences) HOT</span><br><span class="line">F2(Quickly locate the wrong line)</span><br><span class="line">option+command+V(generate locate variable)</span><br><span class="line">shift+command+enter(generate some code)</span><br><span class="line">option+enter(generate some method)</span><br><span class="line">command+R(replace)</span><br><span class="line">shift+F6(rename)</span><br><span class="line">option+command+V(Extract Variable)</span><br><span class="line">option+command+C(Extract static Variable) HOT</span><br><span class="line">option+command+F(Extract field Variable)</span><br><span class="line">option+command+P(Extract field Variable into method)</span><br><span class="line">option+command+M(Extract some code to be a new method)HOT</span><br><span class="line">shift+command+F8(show all breakPoints)</span><br><span class="line">shift+command+V(copy history)</span><br><span class="line">shift+option+command+U(show maven dependencies)</span><br><span class="line">option+command+U(show class inherit) HOT</span><br><span class="line">ctrl+option+H(call method or be called history)</span><br><span class="line">ctrl+N(Generate anything)</span><br><span class="line">ctrl+w(select something)</span><br><span class="line">ctrl+&lt; or &gt; (move up or down next method) HOT</span><br><span class="line">cmd+option+T (surround) HOT</span><br></pre></td></tr></table></figure>
<h1 id="Problem-Solution"><a href="#Problem-Solution" class="headerlink" title="Problem Solution"></a>Problem Solution</h1><h2 id="编译出现莫名其妙的找不到符号的Error"><a href="#编译出现莫名其妙的找不到符号的Error" class="headerlink" title="编译出现莫名其妙的找不到符号的Error"></a>编译出现莫名其妙的找不到符号的Error</h2><p>如果找不到符号的错误行数，刚好式同包下的某个类找不到符号报错，那么可能式idea的类编译顺序冲突了，找到报错行上引用到的类，先单独编译应用到的类，再编译报错的类，最后编译整个项目就可以了。</p>
<h2 id="非静默模式下断点失效"><a href="#非静默模式下断点失效" class="headerlink" title="非静默模式下断点失效"></a>非静默模式下断点失效</h2><p>断点处提示：idea debug no executable code found<br>这个一般是class和idea的代码不一致导致的。<br>解决办法：<br>1、invalidate Caches/Restart<br>2、rebuild Project<br>3、class的输出路径正确<br>4、我自己是因为jboss的On ‘update’ action 被设置成了Restart Server，热部署应该改为：Update classes and resources</p>
<h2 id="某个jar依赖冲突问题的解决"><a href="#某个jar依赖冲突问题的解决" class="headerlink" title="某个jar依赖冲突问题的解决"></a>某个jar依赖冲突问题的解决</h2><p>公司项目中cglib的包依赖了二个log4j的包，导致控制台启动会报错。 删除项目输出目录下的lib，设置依赖jar的scope为provided。<br><img src="https://cdn.jsdelivr.net/gh/coding-by-feng/oss@master/uPic/7vAT8L.png" alt><br>然后重新部署启动就可以了。</p>
<h2 id="debug启动微服务莫名其妙卡住的情况"><a href="#debug启动微服务莫名其妙卡住的情况" class="headerlink" title="debug启动微服务莫名其妙卡住的情况"></a>debug启动微服务莫名其妙卡住的情况</h2><p>竟然是因为我在某个方法的声明上打了断点，然后我静默断点时就可以debug启动微服务了：<br><img src="https://cdn.jsdelivr.net/gh/coding-by-feng/oss@master/uPic/Qtfqng.png" alt><br>于是我果断把断点去掉，然后再检查一遍有没有打到方法声明上的断点，全都取消之后重启debug就可以了。</p>
<h2 id="记录Idea关于Maven依赖的一个致命Bug"><a href="#记录Idea关于Maven依赖的一个致命Bug" class="headerlink" title="记录Idea关于Maven依赖的一个致命Bug"></a>记录Idea关于Maven依赖的一个致命Bug</h2><blockquote>
<p>基于版本2019.3.4</p>
</blockquote>
<p>公司的微服务架构的用的Maven管理依赖，关于流程flowable的的模块ngbip-flow及其几个子模块我放在一个单独的文件夹下面；</p>
<p>另外的一个项目也是基于微服务架构依赖ngbip-flow及其几个子模块，然后由于启动报了个莫名其妙的错误，于是我删掉了项目对公司自研的所有依赖，重新引入；</p>
<p>但是这个时候idea移动将ngbip-flow的几个模块的依赖强制指向了上面提到的单独的文件夹下面的ngbip-flow几个子模块的代码文件，不走maven去依赖了，我TM是不同的文件夹（不同的工作区间啊，打开的是不同的idea窗口）；</p>
<p>最后的硬核解决方法是，将原来的单独文件夹重命名个名字，这个时候另外的项目一下子就自动重新引入ngbip-flow的maven依赖，不会强制走开发机的其他文件夹下面的依赖，然后我再把文件夹名字改回来即可。</p>
<h2 id="Maven代码不能指向本地工程module代码"><a href="#Maven代码不能指向本地工程module代码" class="headerlink" title="Maven代码不能指向本地工程module代码"></a>Maven代码不能指向本地工程module代码</h2><p>如果出现idea的Modules已经存在，但是代码不能通过Maven依赖到已经引入的module时（此时Maven管理界面可能会出现已经引入的model的maven可视化没有出现），这个时候在工程的Modules删除重新引入应该就可以了。</p>
<h2 id="Idea出现所有引导到的类报错，连jdk的基础类也报错的情况"><a href="#Idea出现所有引导到的类报错，连jdk的基础类也报错的情况" class="headerlink" title="Idea出现所有引导到的类报错，连jdk的基础类也报错的情况"></a>Idea出现所有引导到的类报错，连jdk的基础类也报错的情况</h2><p>可能是不了心设置了Editor-&gt;File Type中忽略了*.class导致的。<br>如果是项目引入自己项目的代码也报错，可以删掉模块重新import。</p>
<h2 id="Idea关闭写代码形参提示（会导致变卡）"><a href="#Idea关闭写代码形参提示（会导致变卡）" class="headerlink" title="Idea关闭写代码形参提示（会导致变卡）"></a>Idea关闭写代码形参提示（会导致变卡）</h2><p><img src="https://cdn.jsdelivr.net/gh/coding-by-feng/oss@master/uPic/RVmJT6.png" alt="https://cdn.jsdelivr.net/gh/coding-by-feng/oss@master/uPic/RVmJT6.png"></p>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-Hans">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2020/04/04/Java-Bean-Validation-Basics/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="Fengorz">
      <meta itemprop="description" content="A Quiet Departure.">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Feng's Blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/2020/04/04/Java-Bean-Validation-Basics/" class="post-title-link" itemprop="url">Java Bean Validation Basics</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2020-04-04 10:20:12" itemprop="dateCreated datePublished" datetime="2020-04-04T10:20:12+08:00">2020-04-04</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2020-07-30 10:36:39" itemprop="dateModified" datetime="2020-07-30T10:36:39+08:00">2020-07-30</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">In</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Java/" itemprop="url" rel="index"><span itemprop="name">Java</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <blockquote>
<p>参考来自www.baeldung.com的多篇文章</p>
</blockquote>
<h1 id="Java-Bean-Validation的历史演变"><a href="#Java-Bean-Validation的历史演变" class="headerlink" title="Java Bean Validation的历史演变"></a>Java Bean Validation的历史演变</h1><ul>
<li>原本以为JSR303就已经是够了，后面才发现这只是initial version，也就是Bean Validation 1.0；</li>
<li>后面又推出了JSR349（Bean Validation 1.1）</li>
<li>而最新版本是<a href="https://jcp.org/en/jsr/detail?id=380" target="_blank" rel="noopener">JSR380</a>（<a href="https://beanvalidation.org/2.0/" target="_blank" rel="noopener">Bean Validation 2.0</a>）</li>
</ul>
<h1 id="依赖包"><a href="#依赖包" class="headerlink" title="依赖包"></a>依赖包</h1><p>在不使用第三方的框架提供的校验功能（比如Spring，Spring默认会引入依赖并对标准做了一些具体的实现）的情况下，想要使用Java Bean Validation的功能需要先引入标准API依赖(这里以2.0版本为准)：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&lt;dependency&gt;</span><br><span class="line">    &lt;groupId&gt;javax.validation&lt;/groupId&gt;</span><br><span class="line">    &lt;artifactId&gt;validation-api&lt;/artifactId&gt;</span><br><span class="line">    &lt;version&gt;2.0.0.Final&lt;/version&gt;</span><br><span class="line">&lt;/dependency&gt;</span><br></pre></td></tr></table></figure></p>
<p>除了引入标准之外，还要引入标准的实现：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">&lt;dependency&gt;</span><br><span class="line">    &lt;groupId&gt;org.hibernate.validator&lt;/groupId&gt;</span><br><span class="line">    &lt;artifactId&gt;hibernate-validator&lt;/artifactId&gt;</span><br><span class="line">    &lt;version&gt;6.0.2.Final&lt;/version&gt;</span><br><span class="line">&lt;/dependency&gt;</span><br><span class="line">&lt;dependency&gt;</span><br><span class="line">    &lt;groupId&gt;org.hibernate.validator&lt;/groupId&gt;</span><br><span class="line">    &lt;artifactId&gt;hibernate-validator-annotation-processor&lt;/artifactId&gt;</span><br><span class="line">    &lt;version&gt;6.0.2.Final&lt;/version&gt;</span><br><span class="line">&lt;/dependency&gt;</span><br></pre></td></tr></table></figure></p>
<p>这里只是引入的hibernate的validator部分，没有引入持久化的那部分。<br>再引入el表达式的依赖：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">&lt;dependency&gt;</span><br><span class="line">    &lt;groupId&gt;javax.el&lt;/groupId&gt;</span><br><span class="line">    &lt;artifactId&gt;javax.el-api&lt;/artifactId&gt;</span><br><span class="line">    &lt;version&gt;3.0.0&lt;/version&gt;</span><br><span class="line">&lt;/dependency&gt;</span><br><span class="line"> </span><br><span class="line">&lt;dependency&gt;</span><br><span class="line">    &lt;groupId&gt;org.glassfish.web&lt;/groupId&gt;</span><br><span class="line">    &lt;artifactId&gt;javax.el&lt;/artifactId&gt;</span><br><span class="line">    &lt;version&gt;2.2.6&lt;/version&gt;</span><br><span class="line">&lt;/dependency&gt;</span><br></pre></td></tr></table></figure></p>
<p>如果没有引入el表达式的依赖可能会报错：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">HV000183: Unable to load ‘javax.el.ExpressionFactory&apos;. Check that you have the EL dependencies on the classpath, or use ParameterMessageInterpolator instead</span><br></pre></td></tr></table></figure></p>
<h1 id="可以通过Validator对Bean进行数据校验"><a href="#可以通过Validator对Bean进行数据校验" class="headerlink" title="可以通过Validator对Bean进行数据校验"></a>可以通过Validator对Bean进行数据校验</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">@Test</span><br><span class="line">public void test6() &#123;</span><br><span class="line">    FetchWordResultDTO fetchWordResultDTO = new FetchWordResultDTO();</span><br><span class="line">    ValidatorFactory factory = Validation.buildDefaultValidatorFactory();</span><br><span class="line">    Validator validator = factory.getValidator();</span><br><span class="line">    Set&lt;ConstraintViolation&lt;FetchWordResultDTO&gt;&gt; results = validator.validate(fetchWordResultDTO);</span><br><span class="line">    for (ConstraintViolation&lt;FetchWordResultDTO&gt; result : results) &#123;</span><br><span class="line">        System.out.println(result.getPropertyPath());</span><br><span class="line">        System.out.println(result.getMessage());</span><br><span class="line">        System.out.println(result.getInvalidValue());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h1 id="校验注解"><a href="#校验注解" class="headerlink" title="校验注解"></a>校验注解</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line">空检查</span><br><span class="line">@Null       验证对象是否为null</span><br><span class="line">@NotNull    验证对象是否不为null, 无法查检长度为0的字符串</span><br><span class="line">@NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.</span><br><span class="line">@NotEmpty 检查约束元素是否为NULL或者是EMPTY.</span><br><span class="line"> </span><br><span class="line">Booelan检查</span><br><span class="line">@AssertTrue     验证 Boolean 对象是否为 true  </span><br><span class="line">@AssertFalse    验证 Boolean 对象是否为 false  </span><br><span class="line"> </span><br><span class="line">长度检查</span><br><span class="line">@Size(min=, max=) 验证对象（Array,Collection,Map,String）长度是否在给定的范围之内  </span><br><span class="line">@Length(min=, max=) Validates that the annotated string is between min and max included.</span><br><span class="line"> </span><br><span class="line">日期检查</span><br><span class="line">@Past           验证 Date 和 Calendar 对象是否在当前时间之前  </span><br><span class="line">@Future     验证 Date 和 Calendar 对象是否在当前时间之后  </span><br><span class="line">@Pattern    验证 String 对象是否符合正则表达式的规则</span><br><span class="line">@Past and @PastOrPresent – validate that a date value is in the past or the past including the present; can be applied to date types including those added in Java 8</span><br><span class="line">@Future and @FutureOrPresent – validates that a date value is in the future, or in the future including the present</span><br><span class="line"> </span><br><span class="line">数值检查，建议使用在Stirng,Integer类型，不建议使用在int类型上，因为表单值为“”时无法转换为int，但可以转换为Stirng为&quot;&quot;,Integer为null</span><br><span class="line">@Min            验证 Number 和 String 对象是否大等于指定的值  </span><br><span class="line">@Max            验证 Number 和 String 对象是否小等于指定的值  </span><br><span class="line">@DecimalMax 被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度</span><br><span class="line">@DecimalMin 被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度</span><br><span class="line">@Digits     验证 Number 和 String 的构成是否合法  </span><br><span class="line">@Digits(integer=,fraction=) 验证字符串是否是符合指定格式的数字，interger指定整数精度，fraction指定小数精度。</span><br><span class="line">@Positive and @PositiveOrZero – apply to numeric values and validate that they are strictly positive, or positive including 0</span><br><span class="line">@Negative and @NegativeOrZero – apply to numeric values and validate that they are strictly negative, or negative including 0</span><br><span class="line"> </span><br><span class="line">@Range(min=, max=) 检查数字是否介于min和max之间.</span><br><span class="line">@Range(min=10000,max=50000,message=&quot;range.bean.wage&quot;)</span><br><span class="line">private BigDecimal wage;</span><br><span class="line"> </span><br><span class="line">@Valid 递归的对关联对象进行校验, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验.(是否进行递归验证)</span><br><span class="line">@CreditCardNumber信用卡验证</span><br><span class="line">@Email  验证是否是邮件地址，如果为null,不进行验证，算通过验证。</span><br><span class="line">@ScriptAssert(lang= ,script=, alias=)</span><br><span class="line">@URL(protocol=,host=, port=,regexp=, flags=)</span><br><span class="line">// 参考 https://www.cnblogs.com/yangzhilong/p/3724967.html</span><br></pre></td></tr></table></figure>
<h1 id="Validation-in-Spring-Boot"><a href="#Validation-in-Spring-Boot" class="headerlink" title="Validation in Spring Boot"></a>Validation in Spring Boot</h1><h2 id="利用-Valid对数据做优雅的校验"><a href="#利用-Valid对数据做优雅的校验" class="headerlink" title="利用@Valid对数据做优雅的校验"></a>利用@Valid对数据做优雅的校验</h2><p>校验异常会抛出MethodArgumentNotValidException，然后可以Spring的机制定义全局异常处理器。<br>Demo of Controller:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">@PostMapping(&quot;/storeFetchWordResult&quot;)</span><br><span class="line">public R storeFetchWordResult(@RequestBody @Valid FetchWordResultDTO fetchWordResultDTO) &#123;</span><br><span class="line">    // do something</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>全局异常处理器:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">@Slf4j</span><br><span class="line">@ControllerAdvice</span><br><span class="line">public class GlobalValidExceptionHandler &#123;</span><br><span class="line"></span><br><span class="line">    @ResponseBody</span><br><span class="line">    @ExceptionHandler(&#123;MethodArgumentNotValidException.class&#125;)</span><br><span class="line">    public R handleValidException(MethodArgumentNotValidException e)&#123;</span><br><span class="line">        //日志记录错误信息</span><br><span class="line">        log.error(Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage());</span><br><span class="line">        //将错误信息返回给前台</span><br><span class="line">        return R.failed(CommonConstants.FAIL, Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">// 优化之后的全局异常处理器</span><br><span class="line"></span><br><span class="line">@Slf4j</span><br><span class="line">@RestControllerAdvice</span><br><span class="line">public class GlobalExceptionHandler &#123;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    @ExceptionHandler(&#123;MethodArgumentNotValidException.class&#125;)</span><br><span class="line">    @ResponseStatus(HttpStatus.BAD_REQUEST)</span><br><span class="line">    public R handleValidException(MethodArgumentNotValidException e)&#123;</span><br><span class="line">        //日志记录错误信息</span><br><span class="line">        final String errorMessage = EnhancedExceptionUtils.getLogMessage(e);</span><br><span class="line">        log.error(errorMessage);</span><br><span class="line">        //将错误信息返回给前台</span><br><span class="line">        return R.failed(CommonConstants.FAIL, errorMessage);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>某知名博客文章的全局异常处理器demo（多个字段的错误校验可以更加直观地展示出来）：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">@ResponseStatus(HttpStatus.BAD_REQUEST)</span><br><span class="line">@ExceptionHandler(MethodArgumentNotValidException.class)</span><br><span class="line">public Map&lt;String, String&gt; handleValidationExceptions(</span><br><span class="line">  MethodArgumentNotValidException ex) &#123;</span><br><span class="line">    Map&lt;String, String&gt; errors = new HashMap&lt;&gt;();</span><br><span class="line">    ex.getBindingResult().getAllErrors().forEach((error) -&gt; &#123;</span><br><span class="line">        String fieldName = ((FieldError) error).getField();</span><br><span class="line">        String errorMessage = error.getDefaultMessage();</span><br><span class="line">        errors.put(fieldName, errorMessage);</span><br><span class="line">    &#125;);</span><br><span class="line">    return errors;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<h2 id="Validated-vs-Valid"><a href="#Validated-vs-Valid" class="headerlink" title="@Validated vs @Valid"></a>@Validated vs @Valid</h2><p><a href="https://blog.csdn.net/qq_27680317/article/details/79970590" target="_blank" rel="noopener">两者的区别</a><br><img src="https://cdn.jsdelivr.net/gh/coding-by-feng/oss@master/uPic/0e8YJB.png" alt></p>
<h2 id="Validated应用在ctl方法的参数的好处"><a href="#Validated应用在ctl方法的参数的好处" class="headerlink" title="@Validated应用在ctl方法的参数的好处"></a>@Validated应用在ctl方法的参数的好处</h2><p>可以直接在形参上注解：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">public ResponseMessage&lt;IPage&lt;PostPhoneInfo&gt;&gt; queryPage(@NotNull Long pageNum, @NotNull Long pageSize, PostPhoneInfo postPhoneInfo) &#123;</span><br><span class="line">    return ResponseMessage.success(postPhoneInfoService.queryPage(pageNum, pageSize, postPhoneInfo));</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>之前我直接想直接采用注解校验入参，不想将校验逻辑带到业务中去，但是使用@Valid无法做到，而Spring封装好的@Validated可以做到。</p>
<h4 id="要注意的地方"><a href="#要注意的地方" class="headerlink" title="要注意的地方"></a>要注意的地方</h4><ul>
<li>校验注解是在方法入参上，则需要在该方法所在的类上添加 @org.springframework.validation.annotation.Validated 注解，在入参前或是在方法上添加启用校验注解都不生效。</li>
<li>如果ctl方法的入参是一个Java Bean承载，那么无需使用@NotNull校验，Spring模式会给一个空实例，@NotNull注解没有意义</li>
<li>使用@Validated分组的时候，比如只需要在某个ctl的方法上指定分组校验时，代码可以这样：<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line"> * 新增 or 更新</span><br><span class="line"> */</span><br><span class="line">@ApiOperation(notes = &quot;保存单条记录&quot;, value = &quot;保存查询单条记录&quot;)</span><br><span class="line">@PostMapping(&quot;/saveOne&quot;)</span><br><span class="line">@Validated(Default.class)</span><br><span class="line">public ResponseMessage&lt;Void&gt; saveOne(@Valid PostPhoneInfoVO postPhoneInfoVO) &#123;</span><br><span class="line">    postPhoneInfoService.saveOne(postPhoneInfoVO);</span><br><span class="line">    return ResponseMessage.success();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h2 id="Custom-Validation-MessageSource-in-Spring-Boot"><a href="#Custom-Validation-MessageSource-in-Spring-Boot" class="headerlink" title="Custom Validation MessageSource in Spring Boot"></a>Custom Validation MessageSource in Spring Boot</h2><p>MessageSource是Spring Boot很强大的一个特性，最为明显的是可以用于国际化处理。</p>
<h4 id="一个登陆表单的demo"><a href="#一个登陆表单的demo" class="headerlink" title="一个登陆表单的demo"></a>一个登陆表单的demo</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">public class LoginForm &#123;</span><br><span class="line"> </span><br><span class="line">    @NotEmpty(message = &quot;&#123;email.notempty&#125;&quot;)</span><br><span class="line">    @Email</span><br><span class="line">    private String email;</span><br><span class="line"> </span><br><span class="line">    @NotNull</span><br><span class="line">    private String password;</span><br><span class="line"> </span><br><span class="line">    // standard getter and setters</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="定义MessageSource-Bean"><a href="#定义MessageSource-Bean" class="headerlink" title="定义MessageSource Bean"></a>定义MessageSource Bean</h4><p>ReloadableResourceBundleMessageSource是最常用的MessageSource实现类<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">@Bean</span><br><span class="line">public MessageSource messageSource() &#123;</span><br><span class="line">    ReloadableResourceBundleMessageSource messageSource</span><br><span class="line">      = new ReloadableResourceBundleMessageSource();</span><br><span class="line">     </span><br><span class="line">    messageSource.setBasename(&quot;classpath:messages&quot;);</span><br><span class="line">    messageSource.setDefaultEncoding(&quot;UTF-8&quot;);</span><br><span class="line">    return messageSource;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<h4 id="定义LocalValidatorFactoryBean来注册上面的MessageSource-Bean"><a href="#定义LocalValidatorFactoryBean来注册上面的MessageSource-Bean" class="headerlink" title="定义LocalValidatorFactoryBean来注册上面的MessageSource Bean"></a>定义LocalValidatorFactoryBean来注册上面的MessageSource Bean</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">@Bean</span><br><span class="line">public LocalValidatorFactoryBean getValidator() &#123;</span><br><span class="line">    LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();</span><br><span class="line">    bean.setValidationMessageSource(messageSource());</span><br><span class="line">    return bean;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="定义国际化配置文件"><a href="#定义国际化配置文件" class="headerlink" title="定义国际化配置文件"></a>定义国际化配置文件</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"># messages.properties</span><br><span class="line">email.notempty=Please provide valid email id.</span><br><span class="line"># messages_fr.properties</span><br><span class="line">email.notempty=Veuillez fournir un identifiant de messagerie valide.</span><br></pre></td></tr></table></figure>
<h2 id="Method-Constraints-with-Bean-Validation-2-0"><a href="#Method-Constraints-with-Bean-Validation-2-0" class="headerlink" title="Method Constraints with Bean Validation 2.0"></a>Method Constraints with Bean Validation 2.0</h2><p>这个特性可以用于哪些比较复杂又常用的数据校验，而且校验逻辑是JSR380的注解不能实现的，所以需要自定义校验。</p>
<ul>
<li>Single-parameter Constraints</li>
<li>Cross-Parameter Constraints</li>
<li>return constraints</li>
</ul>
<h4 id="自定义校验注解实现Cross-Parameter-Constraints"><a href="#自定义校验注解实现Cross-Parameter-Constraints" class="headerlink" title="自定义校验注解实现Cross-Parameter Constraints"></a>自定义校验注解实现Cross-Parameter Constraints</h4><p>比如以下Demo：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">@ConsistentDateParameters</span><br><span class="line">public void createReservation(LocalDate begin, </span><br><span class="line">  LocalDate end, Customer customer) &#123;</span><br><span class="line">    // ...</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>如要有个业务场景是要求：begin必须比当前时间大，而且end必须比begin大的情况，那么使用JSR380的内置注解就无法实现了，所以要自定义校验注解和注解校验器。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">@Constraint(validatedBy = ConsistentDateParameterValidator.class)</span><br><span class="line">@Target(&#123; METHOD, CONSTRUCTOR &#125;)</span><br><span class="line">@Retention(RUNTIME)</span><br><span class="line">@Documented</span><br><span class="line">public @interface ConsistentDateParameters &#123;</span><br><span class="line"> </span><br><span class="line">    String message() default</span><br><span class="line">      &quot;End date must be after begin date and both must be in the future&quot;;</span><br><span class="line"> </span><br><span class="line">    Class&lt;?&gt;[] groups() default &#123;&#125;;</span><br><span class="line"> </span><br><span class="line">    Class&lt;? extends Payload&gt;[] payload() default &#123;&#125;;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">@SupportedValidationTarget(ValidationTarget.PARAMETERS)</span><br><span class="line">public class ConsistentDateParameterValidator </span><br><span class="line">  implements ConstraintValidator&lt;ConsistentDateParameters, Object[]&gt; &#123;</span><br><span class="line"> </span><br><span class="line">    @Override</span><br><span class="line">    public boolean isValid(</span><br><span class="line">      Object[] value, </span><br><span class="line">      ConstraintValidatorContext context) &#123;</span><br><span class="line">         </span><br><span class="line">        if (value[0] == null || value[1] == null) &#123;</span><br><span class="line">            return true;</span><br><span class="line">        &#125;</span><br><span class="line"> </span><br><span class="line">        if (!(value[0] instanceof LocalDate) </span><br><span class="line">          || !(value[1] instanceof LocalDate)) &#123;</span><br><span class="line">            throw new IllegalArgumentException(</span><br><span class="line">              &quot;Illegal method signature, expected two parameters of type LocalDate.&quot;);</span><br><span class="line">        &#125;</span><br><span class="line"> </span><br><span class="line">        return ((LocalDate) value[0]).isAfter(LocalDate.now()) </span><br><span class="line">          &amp;&amp; ((LocalDate) value[0]).isBefore((LocalDate) value[1]);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="自定义返回值的校验注解"><a href="#自定义返回值的校验注解" class="headerlink" title="自定义返回值的校验注解"></a>自定义返回值的校验注解</h4><p>比如要校验某个复杂的对象Reservation：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">public class ReservationManagement &#123;</span><br><span class="line"> </span><br><span class="line">    @ValidReservation</span><br><span class="line">    public Reservation getReservationsById(int id) &#123;</span><br><span class="line">        return null;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>自定义注解，注意注解的范围可以是构造器CONSTRUCTOR：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">@Constraint(validatedBy = ValidReservationValidator.class)</span><br><span class="line">@Target(&#123; METHOD, CONSTRUCTOR &#125;)</span><br><span class="line">@Retention(RUNTIME)</span><br><span class="line">@Documented</span><br><span class="line">public @interface ValidReservation &#123;</span><br><span class="line">    String message() default &quot;End date must be after begin date &quot;</span><br><span class="line">      + &quot;and both must be in the future, room number must be bigger than 0&quot;;</span><br><span class="line"> </span><br><span class="line">    Class&lt;?&gt;[] groups() default &#123;&#125;;</span><br><span class="line"> </span><br><span class="line">    Class&lt;? extends Payload&gt;[] payload() default &#123;&#125;;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>校验器的具体实现：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">public class ValidReservationValidator</span><br><span class="line">  implements ConstraintValidator&lt;ValidReservation, Reservation&gt; &#123;</span><br><span class="line"> </span><br><span class="line">    @Override</span><br><span class="line">    public boolean isValid(</span><br><span class="line">      Reservation reservation, ConstraintValidatorContext context) &#123;</span><br><span class="line"> </span><br><span class="line">        if (reservation == null) &#123;</span><br><span class="line">            return true;</span><br><span class="line">        &#125;</span><br><span class="line"> </span><br><span class="line">        if (!(reservation instanceof Reservation)) &#123;</span><br><span class="line">            throw new IllegalArgumentException(&quot;Illegal method signature, &quot;</span><br><span class="line">            + &quot;expected parameter of type Reservation.&quot;);</span><br><span class="line">        &#125;</span><br><span class="line"> </span><br><span class="line">        if (reservation.getBegin() == null</span><br><span class="line">          || reservation.getEnd() == null</span><br><span class="line">          || reservation.getCustomer() == null) &#123;</span><br><span class="line">            return false;</span><br><span class="line">        &#125;</span><br><span class="line"> </span><br><span class="line">        return (reservation.getBegin().isAfter(LocalDate.now())</span><br><span class="line">          &amp;&amp; reservation.getBegin().isBefore(reservation.getEnd())</span><br><span class="line">          &amp;&amp; reservation.getRoom() &gt; 0);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>然后就可以在构造器方法上使用注解了：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">public class Reservation &#123;</span><br><span class="line"> </span><br><span class="line">    @ValidReservation</span><br><span class="line">    public Reservation(</span><br><span class="line">      LocalDate begin, </span><br><span class="line">      LocalDate end, </span><br><span class="line">      Customer customer, </span><br><span class="line">      int room) &#123;</span><br><span class="line">        this.begin = begin;</span><br><span class="line">        this.end = end;</span><br><span class="line">        this.customer = customer;</span><br><span class="line">        this.room = room;</span><br><span class="line">    &#125;</span><br><span class="line"> </span><br><span class="line">    // properties, getters, and setters</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<h4 id="级联校验-嵌套校验（Cascaded-Validation）"><a href="#级联校验-嵌套校验（Cascaded-Validation）" class="headerlink" title="级联校验 || 嵌套校验（Cascaded Validation）"></a>级联校验 || 嵌套校验（Cascaded Validation）</h4><p>想要校验对象里面的成员属性内部的相关校验，需要再成员属性声明加上@Valid注解，如：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">public class Reservation &#123;</span><br><span class="line"> </span><br><span class="line">    @Valid</span><br><span class="line">    private Customer customer;</span><br><span class="line">     </span><br><span class="line">    @Positive</span><br><span class="line">    private int room;</span><br><span class="line">     </span><br><span class="line">    // further properties, constructor, getters and setters</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<h1 id="Validating-Container-Elements-with-Bean-Validation-2-0"><a href="#Validating-Container-Elements-with-Bean-Validation-2-0" class="headerlink" title="Validating Container Elements with Bean Validation 2.0"></a>Validating Container Elements with Bean Validation 2.0</h1><h2 id="注意内置的校验还可以用于集合的泛型定义"><a href="#注意内置的校验还可以用于集合的泛型定义" class="headerlink" title="注意内置的校验还可以用于集合的泛型定义"></a>注意内置的校验还可以用于集合的泛型定义</h2><p>比如下面Customer前面的@NotNull：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">public class ReservationManagement &#123;</span><br><span class="line">    @NotNull</span><br><span class="line">    @Size(min = 1)</span><br><span class="line">    public List&lt;@NotNull Customer&gt; getAllCustomers() &#123;</span><br><span class="line">        return null;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>再比如：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">public class Customer &#123;    </span><br><span class="line">     List&lt;@NotBlank(message=&quot;Address must not be blank&quot;) String&gt; addresses;</span><br><span class="line">     </span><br><span class="line">    // standard getters, setters </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">public class CustomerMap &#123;</span><br><span class="line">     </span><br><span class="line">    private Map&lt;@Email String, @NotNull Customer&gt; customers;</span><br><span class="line">     </span><br><span class="line">    // standard getters, setters</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="Optional-Values"><a href="#Optional-Values" class="headerlink" title="Optional Values"></a>Optional Values</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">private Integer age;</span><br><span class="line"> </span><br><span class="line">public Optional&lt;@Min(18) Integer&gt; getAge() &#123;</span><br><span class="line">    return Optional.ofNullable(age);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="非泛型容器的元素（Non-Generic-Container-Elements）"><a href="#非泛型容器的元素（Non-Generic-Container-Elements）" class="headerlink" title="非泛型容器的元素（Non-Generic Container Elements）"></a>非泛型容器的元素（Non-Generic Container Elements）</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">@Min(1)</span><br><span class="line">private OptionalInt numberOfOrders;</span><br></pre></td></tr></table></figure>
<h1 id="Problem-Solution"><a href="#Problem-Solution" class="headerlink" title="Problem Solution"></a>Problem Solution</h1><h2 id="HV000030-No-validator-could-be-found-for-type-java-lang-Integer"><a href="#HV000030-No-validator-could-be-found-for-type-java-lang-Integer" class="headerlink" title="HV000030: No validator could be found for type: java.lang.Integer."></a>HV000030: No validator could be found for type: java.lang.Integer.</h2><p><a href="https://blog.csdn.net/xiaobingtao/article/details/41866235" target="_blank" rel="noopener">https://blog.csdn.net/xiaobingtao/article/details/41866235</a></p>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-Hans">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2019/10/15/网络、密码与安全/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="Fengorz">
      <meta itemprop="description" content="A Quiet Departure.">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Feng's Blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/2019/10/15/网络、密码与安全/" class="post-title-link" itemprop="url">网络、密码与安全</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2019-10-15 21:13:59" itemprop="dateCreated datePublished" datetime="2019-10-15T21:13:59+08:00">2019-10-15</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2020-07-30 10:28:26" itemprop="dateModified" datetime="2020-07-30T10:28:26+08:00">2020-07-30</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">In</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/网络安全/" itemprop="url" rel="index"><span itemprop="name">网络安全</span></a>
                </span>
                  , 
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/网络安全/网络/" itemprop="url" rel="index"><span itemprop="name">网络</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <h1 id="TodoItem"><a href="#TodoItem" class="headerlink" title="TodoItem"></a>TodoItem</h1><h2 id="JWT-todo"><a href="#JWT-todo" class="headerlink" title="JWT todo"></a>JWT todo</h2><h2 id="互联网-20-大安全隐患-todo"><a href="#互联网-20-大安全隐患-todo" class="headerlink" title="互联网 20 大安全隐患 todo"></a>互联网 20 大安全隐患 todo</h2><h4 id="CSRF-攻击的应对之道-todo"><a href="#CSRF-攻击的应对之道-todo" class="headerlink" title="CSRF 攻击的应对之道 todo"></a>CSRF 攻击的应对之道 todo</h4><p><a href="https://www.ibm.com/developerworks/cn/web/1102_niugang_csrf/" target="_blank" rel="noopener">https://www.ibm.com/developerworks/cn/web/1102_niugang_csrf/</a></p>
<p><a href="https://segmentfault.com/a/1190000006944760?utm_source=tag-newest" target="_blank" rel="noopener">https://segmentfault.com/a/1190000006944760?utm_source=tag-newest</a></p>
<p><a href="https://www.cnblogs.com/hyddd/archive/2009/04/09/1432744.html" target="_blank" rel="noopener">https://www.cnblogs.com/hyddd/archive/2009/04/09/1432744.html</a></p>
<h2 id="RS256加密算法研究-todo"><a href="#RS256加密算法研究-todo" class="headerlink" title="RS256加密算法研究 todo"></a>RS256加密算法研究 todo</h2><h2 id="http-vs-https-todo"><a href="#http-vs-https-todo" class="headerlink" title="http vs https todo"></a>http vs https todo</h2><h2 id="SSL-vs-TLS-todo"><a href="#SSL-vs-TLS-todo" class="headerlink" title="SSL vs TLS todo"></a>SSL vs TLS todo</h2><h2 id="AES-是对称加密，不安全-todo"><a href="#AES-是对称加密，不安全-todo" class="headerlink" title="AES 是对称加密，不安全? todo"></a>AES 是对称加密，不安全? todo</h2><h2 id="TCP-vs-WebSocket-vs-KCP"><a href="#TCP-vs-WebSocket-vs-KCP" class="headerlink" title="TCP vs WebSocket vs KCP"></a>TCP vs WebSocket vs KCP</h2><h1 id="两种基本的加解密算法类型"><a href="#两种基本的加解密算法类型" class="headerlink" title="两种基本的加解密算法类型"></a>两种基本的加解密算法类型</h1><ol>
<li><p>对称加密（symmetrcic encryption）：密钥只有一个，加密解密为同一个密码，且加解密速度快，典型的对称加密算法有DES、AES，RC5，3DES等；对称加密主要问题是共享秘钥，除你的计算机（客户端）知道另外一台计算机（服务器）的私钥秘钥，否则无法对通信流进行加密解密。解决这个问题的方案非对称秘钥。</p>
</li>
<li><p>非对称加密：使用两个秘钥：公共秘钥和私有秘钥。私有秘钥由一方密码保存（一般是服务器保存），另一方任何人都可以获得公共秘钥。<br>这种密钥成对出现（且根据公钥无法推知私钥，根据私钥也无法推知公钥），加密解密使用不同密钥（公钥加密需要私钥解密，私钥加密需要公钥解密），相对对称加密速度较慢，典型的非对称加密算法有RSA、DSA等。</p>
</li>
</ol>
<h1 id="Http"><a href="#Http" class="headerlink" title="Http"></a>Http</h1><h2 id="Unsupported-Media-Type"><a href="#Unsupported-Media-Type" class="headerlink" title="Unsupported Media Type"></a>Unsupported Media Type</h2><p>在PostMan中调用后端微服务的Post接口，报了这个错，解决方法：<br>Headers增加Content-Type:application/json<br>Body采用raw和JSON(application/json)的方式发送，然后再下方填入json数据。</p>
<h2 id="各种状态"><a href="#各种状态" class="headerlink" title="各种状态"></a>各种状态</h2>
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-Hans">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2020/01/17/Docker汇总/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="Fengorz">
      <meta itemprop="description" content="A Quiet Departure.">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Feng's Blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/2020/01/17/Docker汇总/" class="post-title-link" itemprop="url">Docker汇总</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2020-01-17 09:38:28" itemprop="dateCreated datePublished" datetime="2020-01-17T09:38:28+08:00">2020-01-17</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2020-07-28 00:08:07" itemprop="dateModified" datetime="2020-07-28T00:08:07+08:00">2020-07-28</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">In</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/docker/" itemprop="url" rel="index"><span itemprop="name">docker</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p><a href="http://www.ruanyifeng.com/blog/2018/02/docker-tutorial.html" target="_blank" rel="noopener">参考1</a><br><a href="https://www.jianshu.com/p/ca1623ac7723" target="_blank" rel="noopener">参考2</a></p>
<h1 id="常用命令"><a href="#常用命令" class="headerlink" title="常用命令"></a>常用命令</h1><p><a href="https://www.runoob.com/docker/docker-command-manual.html" target="_blank" rel="noopener">命令大全</a></p>
<h2 id="容器"><a href="#容器" class="headerlink" title="容器"></a>容器</h2><h3 id="列出所有容器"><a href="#列出所有容器" class="headerlink" title="列出所有容器"></a>列出所有容器</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker container ls</span><br></pre></td></tr></table></figure>
<h3 id="查看所有容易，包括关闭的"><a href="#查看所有容易，包括关闭的" class="headerlink" title="查看所有容易，包括关闭的"></a>查看所有容易，包括关闭的</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">docker container ls --all</span><br><span class="line">docker ps -a</span><br></pre></td></tr></table></figure>
<h3 id="删除具体的容器，根据container-id"><a href="#删除具体的容器，根据container-id" class="headerlink" title="删除具体的容器，根据container id"></a>删除具体的容器，根据container id</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker container rm c8faeffaaa62</span><br></pre></td></tr></table></figure>
<h3 id="查看容器IP"><a href="#查看容器IP" class="headerlink" title="查看容器IP"></a>查看容器IP</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker inspect 容器ID | grep IPAddress</span><br></pre></td></tr></table></figure>
<h3 id="启动某个容器"><a href="#启动某个容器" class="headerlink" title="启动某个容器"></a>启动某个容器</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker restart 1b4671904bfa</span><br></pre></td></tr></table></figure>
<h3 id="查看容器内存使用情况（支持多个同时查）"><a href="#查看容器内存使用情况（支持多个同时查）" class="headerlink" title="查看容器内存使用情况（支持多个同时查）"></a>查看容器内存使用情况（支持多个同时查）</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker stats containerName1 containerName2</span><br></pre></td></tr></table></figure>
<h3 id="查看日志"><a href="#查看日志" class="headerlink" title="查看日志"></a>查看日志</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker logs -f 122482b4b37f</span><br></pre></td></tr></table></figure>
<h3 id="进入容器"><a href="#进入容器" class="headerlink" title="进入容器"></a>进入容器</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo docker exec -it containerName bash</span><br><span class="line">sudo docker attach 44fc0f0582d9</span><br></pre></td></tr></table></figure>
<h3 id="docker限制容器的内存使用"><a href="#docker限制容器的内存使用" class="headerlink" title="docker限制容器的内存使用"></a>docker限制容器的内存使用</h3><p><a href="https://blog.csdn.net/qq_37611270/article/details/97243704" target="_blank" rel="noopener">https://blog.csdn.net/qq_37611270/article/details/97243704</a></p>
<h2 id="状态信息"><a href="#状态信息" class="headerlink" title="状态信息"></a>状态信息</h2><h2 id="列出docker-name"><a href="#列出docker-name" class="headerlink" title="列出docker name"></a>列出docker name</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo docker inspect -f=&apos;&#123;&#123;.Name&#125;&#125;&apos; $(sudo docker ps -a -q)</span><br></pre></td></tr></table></figure>
<h3 id="列出docker-ip"><a href="#列出docker-ip" class="headerlink" title="列出docker ip"></a>列出docker ip</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo docker inspect -f=&apos;&#123;&#123;.NetworkSettings.IPAddress&#125;&#125;&apos; $(sudo docker ps -a -q)</span><br></pre></td></tr></table></figure>
<h3 id="列出所有容器对应的名称，端口，及ip"><a href="#列出所有容器对应的名称，端口，及ip" class="headerlink" title="列出所有容器对应的名称，端口，及ip"></a>列出所有容器对应的名称，端口，及ip</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker inspect -f=&apos;&#123;&#123;.Name&#125;&#125; &#123;&#123;.NetworkSettings.IPAddress&#125;&#125; &#123;&#123;.HostConfig.PortBindings&#125;&#125;&apos; $(docker ps -aq)</span><br></pre></td></tr></table></figure>
<h3 id="查看状态"><a href="#查看状态" class="headerlink" title="查看状态"></a>查看状态</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">systemctl status docker</span><br></pre></td></tr></table></figure>
<h2 id="数据卷"><a href="#数据卷" class="headerlink" title="数据卷"></a>数据卷</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">docker inspect 容器id</span><br><span class="line"># 可以查看容器信息  “HostConfig下的Binds 可以看到数据卷绑定  Mounts下Souce和Destination也可以看到数据卷绑定信息”</span><br></pre></td></tr></table></figure>
<h1 id="Mysql"><a href="#Mysql" class="headerlink" title="Mysql"></a>Mysql</h1><p><a href="https://www.cnblogs.com/sablier/p/11605606.html" target="_blank" rel="noopener">参考</a><br>目录映射时，容器里面的目录会在容器启动的时候自动创建。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">docker run -p 3306:3306 --name mysql \</span><br><span class="line">-v /usr/local/docker/mysql/conf:/etc/mysql \</span><br><span class="line">-v /usr/local/docker/mysql/logs:/var/log/mysql \</span><br><span class="line">-v /usr/local/docker/mysql/data:/var/lib/mysql \</span><br><span class="line">-e MYSQL_ROOT_PASSWORD=raubbhWy \</span><br><span class="line">-d mysql:5.7</span><br></pre></td></tr></table></figure></p>
<p>进入docker本地连接mysql客户端<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo docker exec -it mysql bash</span><br><span class="line">mysql -uroot -p123456</span><br></pre></td></tr></table></figure></p>
<h1 id="Fastdfs"><a href="#Fastdfs" class="headerlink" title="Fastdfs"></a>Fastdfs</h1><p><a href="https://hub.docker.com/r/season/fastdfs" target="_blank" rel="noopener">season/fastdfs</a><br><a href="http://www.zuidaima.com/blog/4653383732808704.htm" target="_blank" rel="noopener">参考1</a><br><a href="https://blog.502.li/archives/docker-deploy-fastdfs.html" target="_blank" rel="noopener">参考2</a><br><a href="https://v3u.cn/a_id_78" target="_blank" rel="noopener">参考3</a></p>
<h1 id="redis"><a href="#redis" class="headerlink" title="redis"></a>redis</h1><p><a href="https://www.runoob.com/docker/docker-install-redis.html" target="_blank" rel="noopener">https://www.runoob.com/docker/docker-install-redis.html</a></p>
<h1 id="rabbitmq"><a href="#rabbitmq" class="headerlink" title="rabbitmq"></a>rabbitmq</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">docker pull rabbitmq:management</span><br><span class="line">docker run -d --hostname my-rabbit --name some-rabbit -p 15555:15672 rabbitmq:management</span><br></pre></td></tr></table></figure>
<p>默认账号密码：guest和guest</p>
<h1 id="docker跑SpringCloud微服务"><a href="#docker跑SpringCloud微服务" class="headerlink" title="docker跑SpringCloud微服务"></a>docker跑SpringCloud微服务</h1><h1 id="dockerfile-maven"><a href="#dockerfile-maven" class="headerlink" title="dockerfile-maven"></a>dockerfile-maven</h1><h1 id="Dockerfile"><a href="#Dockerfile" class="headerlink" title="Dockerfile"></a>Dockerfile</h1><p>在Docker中创建镜像最常用的方式，就是使用Dockerfile。Dockerfile是一个Docker镜像的描述文件，我们可以理解成火箭发射的A、B、C、D…的步骤。Dockerfile其内部包含了一条条的指令，每一条指令构建一层，因此每一条指令的内容，就是描述该层应当如何构建。<br><a href="https://www.runoob.com/docker/docker-dockerfile.html" target="_blank" rel="noopener">Dockerfile基础知识</a><br><a href="https://www.cnblogs.com/lingfengblogs/p/11093246.html" target="_blank" rel="noopener">Dockerfile命令大全</a></p>
<h2 id="命令"><a href="#命令" class="headerlink" title="命令"></a>命令</h2><h3 id="EXPOSE"><a href="#EXPOSE" class="headerlink" title="EXPOSE"></a>EXPOSE</h3><p><a href="https://blog.csdn.net/qq_17639365/article/details/86655177" target="_blank" rel="noopener">https://blog.csdn.net/qq_17639365/article/details/86655177</a></p>
<h3 id="VOLUME"><a href="#VOLUME" class="headerlink" title="VOLUME"></a>VOLUME</h3><p><a href="https://www.cnblogs.com/ExMan/p/12017896.html" target="_blank" rel="noopener">https://www.cnblogs.com/ExMan/p/12017896.html</a></p>
<ul>
<li>通过docker run命令的-v标识创建的挂载点只能对创建的容器有效。</li>
<li>通过dockerfile的 VOLUME 指令可以在镜像中创建挂载点，这样只要通过该镜像创建的容器都有了挂载点。</li>
<li>还有一个区别是，通过 VOLUME 指令创建的挂载点，无法指定主机上对应的目录，是自动生成的。<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">#test</span><br><span class="line">FROM ubuntu</span><br><span class="line">MAINTAINER hello1</span><br><span class="line">VOLUME [&quot;/data1&quot;,&quot;/data2&quot;]</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>上面的dockfile文件通过VOLUME指令指定了两个挂载点 /data1 和 /data2.</p>
<p>我们通过docker inspect 查看通过该dockerfile创建的镜像生成的容器，可以看到如下信息<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">&quot;Mounts&quot;: [</span><br><span class="line">        &#123;</span><br><span class="line">            &quot;Name&quot;: &quot;d411f6b8f17f4418629d4e5a1ab69679dee369b39e13bb68bed77aa4a0d12d21&quot;,</span><br><span class="line">            &quot;Source&quot;: &quot;/var/lib/docker/volumes/d411f6b8f17f4418629d4e5a1ab69679dee369b39e13bb68bed77aa4a0d12d21/_data&quot;,</span><br><span class="line">            &quot;Destination&quot;: &quot;/data1&quot;,</span><br><span class="line">            &quot;Driver&quot;: &quot;local&quot;,</span><br><span class="line">            &quot;Mode&quot;: &quot;&quot;,</span><br><span class="line">            &quot;RW&quot;: true</span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">            &quot;Name&quot;: &quot;6d3badcf47c4ac5955deda6f6ae56f4aaf1037a871275f46220c14ebd762fc36&quot;,</span><br><span class="line">            &quot;Source&quot;: &quot;/var/lib/docker/volumes/6d3badcf47c4ac5955deda6f6ae56f4aaf1037a871275f46220c14ebd762fc36/_data&quot;,</span><br><span class="line">            &quot;Destination&quot;: &quot;/data2&quot;,</span><br><span class="line">            &quot;Driver&quot;: &quot;local&quot;,</span><br><span class="line">            &quot;Mode&quot;: &quot;&quot;,</span><br><span class="line">            &quot;RW&quot;: true</span><br><span class="line">        &#125;</span><br><span class="line">    ]</span><br></pre></td></tr></table></figure></p>
<h2 id="apt-get更换国内源解决Dockerfile构建速度过慢"><a href="#apt-get更换国内源解决Dockerfile构建速度过慢" class="headerlink" title="apt-get更换国内源解决Dockerfile构建速度过慢"></a>apt-get更换国内源解决Dockerfile构建速度过慢</h2><p>ubuntu和debian的镜像源都要换<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">RUN  sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list</span><br><span class="line">RUN  sed -i &apos;s/deb.debian.org/mirrors.ustc.edu.cn/g&apos; /etc/apt/sources.list</span><br><span class="line">RUN  apt-get clean</span><br><span class="line">RUN  apt-get update</span><br></pre></td></tr></table></figure></p>
<p>或者：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">FROM ubuntu:20.04</span><br><span class="line">RUN sed -i &apos;s/ports.ubuntu.com/mirror.tuna.tsinghua.edu.cn/g&apos; /etc/apt/sources.list</span><br><span class="line">RUN apt-get install vim</span><br></pre></td></tr></table></figure></p>
<p><a href="https://www.cnblogs.com/dakewei/p/12783717.html" target="_blank" rel="noopener">https://www.cnblogs.com/dakewei/p/12783717.html</a></p>
<h3 id="163的镜像"><a href="#163的镜像" class="headerlink" title="163的镜像"></a>163的镜像</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">#更新apt-get源 使用163的源</span><br><span class="line">RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak &amp;&amp; \</span><br><span class="line">    echo &quot;deb http://mirrors.163.com/debian/ jessie main non-free contrib&quot; &gt;/etc/apt/sources.list &amp;&amp; \</span><br><span class="line">    echo &quot;deb http://mirrors.163.com/debian/ jessie-proposed-updates main non-free contrib&quot; &gt;&gt;/etc/apt/sources.list &amp;&amp; \</span><br><span class="line">    echo &quot;deb-src http://mirrors.163.com/debian/ jessie main non-free contrib&quot; &gt;&gt;/etc/apt/sources.list &amp;&amp; \</span><br><span class="line">    echo &quot;deb-src http://mirrors.163.com/debian/ jessie-proposed-updates main non-free contrib&quot; &gt;&gt;/etc/apt/sources.list</span><br></pre></td></tr></table></figure>
<h1 id="docker-compose"><a href="#docker-compose" class="headerlink" title="docker-compose"></a>docker-compose</h1><p><a href="https://www.jianshu.com/p/90bf0e231e5a" target="_blank" rel="noopener">docker-compose.yml文件详解</a><br><a href="https://www.runoob.com/docker/docker-compose.html" target="_blank" rel="noopener">基础</a><br><a href="https://www.cnblogs.com/williamjie/p/9103327.html" target="_blank" rel="noopener">参考1</a></p>
<h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo curl -L &quot;https://github.com/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m)&quot; -o /usr/local/bin/docker-compose</span><br></pre></td></tr></table></figure>
<p>如果从github拉下来安装之后无法执行docker-compose命令的话，可以采用本机电脑下载之后上传到服务器，在chmod修改可执行权限就可以了。</p>
<h2 id="命令-1"><a href="#命令-1" class="headerlink" title="命令"></a>命令</h2><h3 id="后台执行"><a href="#后台执行" class="headerlink" title="后台执行"></a>后台执行</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker-compose up -d</span><br></pre></td></tr></table></figure>
<h2 id="docker-compose中解决depends-on无效问题"><a href="#docker-compose中解决depends-on无效问题" class="headerlink" title="docker-compose中解决depends_on无效问题"></a>docker-compose中解决depends_on无效问题</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">RUN apt-get -q update &amp;&amp; apt-get -qy install netcat</span><br><span class="line"># docker-compose.yml 加上下面</span><br><span class="line">command: sh -c &apos;./wait-for.sh kiwi-microservice-local:5001/actuator/info -- echo kiwi-word-biz already started&apos;</span><br></pre></td></tr></table></figure>
<p><a href="http://www.zyiz.net/tech/detail-98533.html" target="_blank" rel="noopener">http://www.zyiz.net/tech/detail-98533.html</a><br><a href="https://github.com/Eficode/wait-for" target="_blank" rel="noopener">https://github.com/Eficode/wait-for</a></p>
<h1 id="Mac上跑docker"><a href="#Mac上跑docker" class="headerlink" title="Mac上跑docker"></a>Mac上跑docker</h1><p><a href="https://www.runoob.com/docker/macos-docker-install.html" target="_blank" rel="noopener">https://www.runoob.com/docker/macos-docker-install.html</a></p>
<h1 id="docker-service的配置"><a href="#docker-service的配置" class="headerlink" title="docker.service的配置"></a>docker.service的配置</h1><p><a href="https://www.cnblogs.com/nihaorz/p/12131873.html" target="_blank" rel="noopener">https://www.cnblogs.com/nihaorz/p/12131873.html</a></p>
<h1 id="更换国内的镜像"><a href="#更换国内的镜像" class="headerlink" title="更换国内的镜像"></a>更换国内的镜像</h1><p><a href="https://blog.csdn.net/u012081441/article/details/104553145/" target="_blank" rel="noopener">https://blog.csdn.net/u012081441/article/details/104553145/</a><br><a href="https://blog.csdn.net/s_lisheng/article/details/79871086" target="_blank" rel="noopener">https://blog.csdn.net/s_lisheng/article/details/79871086</a></p>
<h1 id="在docker跑nginx的vue项目"><a href="#在docker跑nginx的vue项目" class="headerlink" title="在docker跑nginx的vue项目"></a>在docker跑nginx的vue项目</h1><p><a href="https://www.jianshu.com/p/422b61100273" target="_blank" rel="noopener">https://www.jianshu.com/p/422b61100273</a></p>
<h2 id="nginx80端口被占用修改"><a href="#nginx80端口被占用修改" class="headerlink" title="nginx80端口被占用修改"></a>nginx80端口被占用修改</h2><p><a href="https://jingyan.baidu.com/article/3aed632efb150a701080912f.html" target="_blank" rel="noopener">https://jingyan.baidu.com/article/3aed632efb150a701080912f.html</a></p>
<h1 id="网络"><a href="#网络" class="headerlink" title="网络"></a>网络</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">docker network ls</span><br><span class="line">docker network inspect bridge</span><br></pre></td></tr></table></figure>
<p><a href="https://www.cnblogs.com/chenpython123/p/10823879.html" target="_blank" rel="noopener">https://www.cnblogs.com/chenpython123/p/10823879.html</a></p>
<h1 id="Docker根据名称查询容器ID镜像ID并停止删除"><a href="#Docker根据名称查询容器ID镜像ID并停止删除" class="headerlink" title="Docker根据名称查询容器ID镜像ID并停止删除"></a>Docker根据名称查询容器ID镜像ID并停止删除</h1><p><a href="https://blog.csdn.net/zimou5581/article/details/94012682" target="_blank" rel="noopener">https://blog.csdn.net/zimou5581/article/details/94012682</a></p>
<h1 id="Problem-Solution"><a href="#Problem-Solution" class="headerlink" title="Problem Solution"></a>Problem Solution</h1><h2 id="bash-vi-command-not-found"><a href="#bash-vi-command-not-found" class="headerlink" title="bash: vi: command not found"></a>bash: vi: command not found</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">docker exec -it &lt;container&gt; bash</span><br><span class="line">apt-get update</span><br><span class="line">apt-get install vim</span><br></pre></td></tr></table></figure>
<h2 id="Error-response-from-daemon-Get-https-registry-1-docker-io-v2-net-http-TLS-handshake-timeout"><a href="#Error-response-from-daemon-Get-https-registry-1-docker-io-v2-net-http-TLS-handshake-timeout" class="headerlink" title="Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: TLS handshake timeout"></a>Error response from daemon: Get <a href="https://registry-1.docker.io/v2/" target="_blank" rel="noopener">https://registry-1.docker.io/v2/</a>: net/http: TLS handshake timeout</h2><p><a href="https://blog.csdn.net/BigData_Mining/article/details/87869147" target="_blank" rel="noopener">网上的解决方案</a></p>
<h2 id="Current-command-vanished-from-the-unit-file-execution-of-the-command-list-won’t-be-resumed"><a href="#Current-command-vanished-from-the-unit-file-execution-of-the-command-list-won’t-be-resumed" class="headerlink" title="Current command vanished from the unit file, execution of the command list won’t be resumed."></a>Current command vanished from the unit file, execution of the command list won’t be resumed.</h2><p>可能是有docker的相关进程没有杀干净。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">ps -ef|grep docker</span><br><span class="line">kill -9 pid</span><br></pre></td></tr></table></figure></p>
<h2 id="远程2375连接不上"><a href="#远程2375连接不上" class="headerlink" title="远程2375连接不上"></a>远程2375连接不上</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vi /usr/lib/systemd/system/docker.service</span><br></pre></td></tr></table></figure>
<p>vim进入命令行模式输入?ExecStart，找到如下一行：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ExecStart=/usr/bin/dockerd -H unix://var/run/docker.sock \</span><br></pre></td></tr></table></figure></p>
<p>在后面加上-H tcp://0.0.0.0:2375<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0:2375</span><br></pre></td></tr></table></figure></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">systemctl daemon-reload</span><br></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">service docker restart</span><br></pre></td></tr></table></figure>
<p>之后要注意重启之前的容器。</p>
<h2 id="ERROR-Version-in-“-docker-compose-yml”-is-invalid-You-might-be-seeing-this-error-because-you’re-using-the-wrong-Compose-file-version-Either-specify-a-supported-version-e-g-“2-2”-or-“3-3”"><a href="#ERROR-Version-in-“-docker-compose-yml”-is-invalid-You-might-be-seeing-this-error-because-you’re-using-the-wrong-Compose-file-version-Either-specify-a-supported-version-e-g-“2-2”-or-“3-3”" class="headerlink" title="ERROR: Version in “./docker-compose.yml” is invalid. You might be seeing this error because you’re using the wrong Compose file version. Either specify a supported version (e.g “2.2” or “3.3”)"></a>ERROR: Version in “./docker-compose.yml” is invalid. You might be seeing this error because you’re using the wrong Compose file version. Either specify a supported version (e.g “2.2” or “3.3”)</h2><p>把docker-compose.yml里面的version改一下，改成2.2或3.3（根据提示改）</p>
<h2 id="docker-启动-nginx-访问不了的问题"><a href="#docker-启动-nginx-访问不了的问题" class="headerlink" title="docker 启动 nginx 访问不了的问题"></a>docker 启动 nginx 访问不了的问题</h2><p>如果容器的nginx服务没有启动<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">#  进入容器</span><br><span class="line">/usr/sbin/nginx</span><br><span class="line"># 看下报什么错</span><br></pre></td></tr></table></figure></p>
<h2 id="vue-config-js设置代理之后，nginx反向代理-404"><a href="#vue-config-js设置代理之后，nginx反向代理-404" class="headerlink" title="vue.config.js设置代理之后，nginx反向代理 404"></a>vue.config.js设置代理之后，nginx反向代理 404</h2><p><a href="https://zhuanlan.zhihu.com/p/60833019" target="_blank" rel="noopener">https://zhuanlan.zhihu.com/p/60833019</a><br>/etc/nginx/conf.d/default.conf</p>
<p>nginx关键配置：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">location / &#123;</span><br><span class="line">root /usr/share/nginx/html;</span><br><span class="line">index index.html index.htm;</span><br><span class="line">    try_files $uri $uri/ /index.html;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">location /auth &#123;</span><br><span class="line">	proxy_pass http://kiwi-microservice:9991;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">location /wordBiz &#123;</span><br><span class="line">    proxy_pass http://kiwi-microservice:9991;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">location /code &#123;</span><br><span class="line">    proxy_pass http://kiwi-microservice:9991;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<h2 id="Published-ports-are-discarded-when-using-host-network-mode"><a href="#Published-ports-are-discarded-when-using-host-network-mode" class="headerlink" title="Published ports are discarded when using host network mode"></a>Published ports are discarded when using host network mode</h2><p>host的网络模式不能-p映射端口</p>
<h2 id="OCI-runtime-exec-failed-exec-failed-container-linux-go-349-starting-container-process-caused-“exec-”bash-”-executable-file-not-found-in-PATH”-unknown"><a href="#OCI-runtime-exec-failed-exec-failed-container-linux-go-349-starting-container-process-caused-“exec-”bash-”-executable-file-not-found-in-PATH”-unknown" class="headerlink" title="OCI runtime exec failed: exec failed: container_linux.go:349: starting container process caused “exec: \”bash\”: executable file not found in $PATH”: unknown"></a>OCI runtime exec failed: exec failed: container_linux.go:349: starting container process caused “exec: \”bash\”: executable file not found in $PATH”: unknown</h2><p>三种模式选择一种试试：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">docker exec -it 1e33b26152e1 /bin/sh</span><br><span class="line">docker exec -it 1e33b26152e1 bash</span><br><span class="line">docker exec -it 1e33b26152e1 sh</span><br></pre></td></tr></table></figure></p>
<h2 id="mkdir-can’t-create-directory-‘-tmp’-File-exists"><a href="#mkdir-can’t-create-directory-‘-tmp’-File-exists" class="headerlink" title="mkdir: can’t create directory ‘/tmp’: File exists"></a>mkdir: can’t create directory ‘/tmp’: File exists</h2><p>Dockerfile里面RUN命令创建文件夹的时候注意不要和系统同路径，不然会报错。</p>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  


  
  <nav class="pagination">
    <a class="extend prev" rel="prev" href="/page/8/"><i class="fa fa-angle-left" aria-label="Previous page"></i></a><a class="page-number" href="/">1</a><span class="space">&hellip;</span><a class="page-number" href="/page/8/">8</a><span class="page-number current">9</span><a class="page-number" href="/page/10/">10</a><span class="space">&hellip;</span><a class="page-number" href="/page/25/">25</a><a class="extend next" rel="next" href="/page/10/"><i class="fa fa-angle-right" aria-label="Next page"></i></a>
  </nav>



          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          Table of Contents
        </li>
        <li class="sidebar-nav-overview">
          Overview
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">Fengorz</p>
  <div class="site-description" itemprop="description">A Quiet Departure.</div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">125</span>
          <span class="site-state-item-name">posts</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/categories/">
          
        <span class="site-state-item-count">68</span>
        <span class="site-state-item-name">categories</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/tags/">
          
        <span class="site-state-item-count">87</span>
        <span class="site-state-item-name">tags</span></a>
      </div>
  </nav>
</div>



      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

        

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2020</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Fengorz</span>
</div>
  <div class="powered-by">Powered by <a href="https://hexo.io" class="theme-link" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.org" class="theme-link" rel="noopener" target="_blank">NexT.Gemini</a>
  </div>

        








      </div>
    </footer>
  </div>

  
  <script src="/lib/anime.min.js"></script>
  <script src="/lib/velocity/velocity.min.js"></script>
  <script src="/lib/velocity/velocity.ui.min.js"></script>
<script src="/js/utils.js"></script><script src="/js/motion.js"></script>
<script src="/js/schemes/pisces.js"></script>
<script src="/js/next-boot.js"></script>



  















  

  

</body>
</html>
